diff --git a/bchain/baseparser.go b/bchain/baseparser.go index dfba4ea9..8f7bc08a 100644 --- a/bchain/baseparser.go +++ b/bchain/baseparser.go @@ -8,9 +8,11 @@ import ( "github.com/juju/errors" ) +type AddressFactoryFunc func(string) (Address, error) + // BaseParser implements data parsing/handling functionality base for all other parsers type BaseParser struct { - AddressFactory func(string) (Address, error) + AddressFactory AddressFactoryFunc BlockAddressesToKeep int } @@ -19,6 +21,11 @@ func (p *BaseParser) AddressToOutputScript(address string) ([]byte, error) { return nil, errors.New("AddressToOutputScript: not implemented") } +// OutputScriptToAddresses converts ScriptPubKey to addresses - currently not implemented +func (p *BaseParser) OutputScriptToAddresses(script []byte) ([]string, error) { + return nil, errors.New("OutputScriptToAddresses: not implemented") +} + // ParseBlock parses raw block to our Block struct - currently not implemented func (p *BaseParser) ParseBlock(b []byte) (*Block, error) { return nil, errors.New("ParseBlock: not implemented") diff --git a/bchain/coins/bch/bcashparser.go b/bchain/coins/bch/bcashparser.go index 2be69fa4..95284d84 100644 --- a/bchain/coins/bch/bcashparser.go +++ b/bchain/coins/bch/bcashparser.go @@ -50,8 +50,8 @@ func NewBCashParser(params *chaincfg.Params, c *btc.Configuration) (*BCashParser AddressFactory: func(addr string) (bchain.Address, error) { return newBCashAddress(addr, format) }, BlockAddressesToKeep: c.BlockAddressesToKeep, }, - Params: params, - OutputScriptToAddresses: outputScriptToAddresses, + Params: params, + OutputScriptToAddressesFunc: outputScriptToAddresses, }, AddressFormat: format, } diff --git a/bchain/coins/bch/bcashrpc_test.go b/bchain/coins/bch/bcashrpc_test.go index 4fdabb6c..d5fb5788 100644 --- a/bchain/coins/bch/bcashrpc_test.go +++ b/bchain/coins/bch/bcashrpc_test.go @@ -4,317 +4,42 @@ package bch import ( "blockbook/bchain" - "encoding/hex" + "blockbook/bchain/tests/rpc" "encoding/json" - "flag" - "fmt" - "reflect" "testing" ) -var rpcURL = flag.String("rpcURL", "http://localhost:18031", "RPC URL of backend server") -var rpcUser = flag.String("rpcUser", "rpc", "RPC user of backend server") -var rpcPass = flag.String("rpcPass", "rpc", "RPC password of backend server") -var rpcClient *BCashRPC - -func getRPCConfig() string { - config := `{ - "coin_name": "Bcash", - "rpcURL": "%s", - "rpcUser": "%s", - "rpcPass": "%s", - "rpcTimeout": 25, - "parse": true - }` - - return fmt.Sprintf(config, *rpcURL, *rpcUser, *rpcPass) -} - -func getRPCClient() (*BCashRPC, error) { - if rpcClient == nil { - cfg := json.RawMessage(getRPCConfig()) - c, err := NewBCashRPC(cfg, nil) - if err != nil { - return nil, err - } - cli := c.(*BCashRPC) - cli.Parser, err = NewBCashParser(GetChainParams("main"), cli.ChainConfig) - if err != nil { - return nil, err - } - rpcClient = cli +func getRPCClient(cfg json.RawMessage) (bchain.BlockChain, error) { + c, err := NewBCashRPC(cfg, nil) + if err != nil { + return nil, err } - return rpcClient, nil + cli := c.(*BCashRPC) + cli.Parser, err = NewBCashParser(GetChainParams("test"), cli.ChainConfig) + if err != nil { + return nil, err + } + return cli, nil } -const blockHeight = 1239639 -const blockHash = "0000000075dd9708c23f5830de27c5d644983bb877c575c52926f19be7d80fe2" -const blockHex = "00000020fb79eebaff373687fdd612fd8ffb1717b866f7a7748cef7d6994198000000000bbaec06df359e98bd122726c9f178f4fdaa0fb59b3b86d18e465d53acc33bfda06941f5bffff001d7a6681650f01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0a0357ea12055374617368ffffffff0157966009000000001976a914014dc11b35cafe7605b4c1798a5b86efd788cff488ac0000000002000000014071f84a20eaeac1ba417ba63257087999a1c6401b94cdcf898079036aa00949000000006a4730440220600c88cf5f283d4b607253c1345e9d20bc4d67dc523070ad2f27f4ec337da44a02200f80a2dc8a0b501fb9c7fcb85851e05e83acbaf24b7a0cec5c1026c9cf004383412102e5e90f37c8a8f9ba15c3cce80f2f823bcc222063b7bc46e88ed7cd7d335d110afeffffff0200e1f5050000000017a914ac90ed8510c9a7445b104fd1602341dc2f890d1587795e27ea160000001976a91488f18e19e4a62fce9ab0db1cfb29cc22a058562588ac22ea12000200000001b2c673aede02a4054a8c23e456e581d684f47dadb54083317d6152949d55d94e010000006b483045022100f31a23984a44f485a570a102899e3a25cdf6d1234259e602dbe61f2c3e77e490022069a6a7b013452bd66ed3c11aba22a64559134cd1af3d283730a9b7fb33631cca412103cb05918b81d36c387c791d2accfaefead287a4a30427387fb1095fc0c363ef8efeffffff0200c2eb0b0000000017a914ac90ed8510c9a7445b104fd1602341dc2f890d15878906e1e1160000001976a9147f7ed17e71afc40beac9b8d0b0fb53731161339c88ac56ea1200020000000103365f2950d5d427beac98e2e5658cab90ce9b48350c62c5747dcb14d70f7602010000006b4830450221009acfe9bce502d2ad19d10c9278887f041e07a4f8277d1837733841ff6ea201cc022065a757b167b1b842211531b0b6ee891da19025e692dcb138add4738e8ad9524d412102a69b92783a38bc29c7f669818d922cf8566f41dbc8dd4992e72b69480a8766adfeffffff02b4b157fe160000001976a91414fba45042c5d32455a02e97f5e3c12874df267088ac00e1f505000000001976a9148c5d5ba49d1661f3c07261fe25ce6d849cd40d3c88ac56ea12000200000001768dcdaa8e733e9de87bd4762567e16e362746ff6752a393f5b62f9e1760209b000000006b483045022100df684fea9661ff797aa9e977d6b223e3cff4b661b1f49b61ae4590e48c0f1ebc0220635ebec87bd291b8263f0500797e2de573f94d7ee69dad63ce19add5abf273d5412103639049ceb22afb8c9070fe00562833a4e367c45c5c632daf75e81ea101cc6f2bfeffffff0298f7d3d1160000001976a914bbcd80aacaa6d8fe22bded7fec4746eb605dbf2388ac00e1f505000000001976a9146010d148212eabdec987af9568ed3c16bc8565c388ac56ea12000200000001e06d5b80b1dc384515b51accb247cfe74da3652c204758aeb48b9447e061d624000000006a47304402200252a79712e87e0212802e064dae51b0b93cc27642f6a521f84f522f9713f90702207234f37a4db14b0678d3301c67b7eaadde293394128c346c619aa2baeccfdf4b412103e8ec57f9d6f63d46ff1a83df3463048c5a1f77de7648da8d11d98347e79d260dfeffffff0230932c7f160000001976a91471707ab51d344b3996c4056a9f86659c8452592d88ac20bcbe00000000001976a914cd14f744df519aa04553b65c20a2fd0f7d653cc688ac56ea12000200000001d4d209bc5fb71b8d15a2a97846cec3cca73dc1d86ea66072a5478e59317017cc000000006a47304402207f6dbce56aa6548859bac719fb410859f366f190f63787b2a22339b1a1b338cf02204fee90094758a40e34726018a43b23e9789f1dcfc2da2515684d409c057818f741210372c26fba05c5bd542c1f8ff5bb2d2bebc26565bccd0731a4b6b7cd304eb50ca0feffffff028ecc1a4f160000001976a914e71a68a6fdf8badab6f8639dde10bdc436c4a40988ac00c2eb0b000000001976a914a28bc738fc7af8e0545edc40407cfb05077c60b888ac36ea120002000000013a047d9af4ecc4e7f8fdfded63af66f4e6a6e952f6ac95d905ea234b0a5152d3010000006a473044022028cd96dbaba2c72d36c3bdb5ec2ceff9520142ab045ddbd76732dd0a81147c1c0220394ab87587374ad48153def50abff43e410462456f04147a8b7af141274fa55c412102c01655518abdf62b4f6898d1ab9b90496cf97ee2ed9a4f949e695472fd45d1e0feffffff02ffad805f150000001976a9148c0c65371147f8f7e63e3ff1319be62a554dca9988ac00c2eb0b000000001976a9148c5d5ba49d1661f3c07261fe25ce6d849cd40d3c88ac56ea12000200000001ba548aa7f7d4342e4ba8ba4d0657b06778fb77d1258240be8f42f9f0415da359010000006b483045022100a42c83bf0bb95adc29f63b4c4d4831c0cbf8bb44f2a836db227be6f0208b2a550220746f3a9da3cec8308ff8f1907cdbd7b3d1c7462db5a54abfe68d207ffa159d53412103653ece38ad97d96f6782d5f8ea83a0bb861f69f4bad444c6bfbcac449666e7b4feffffff0240787d01000000001976a914cd14f744df519aa04553b65c20a2fd0f7d653cc688ac9a107ef2120000001976a914b3e12112e6c3614ecd980b76e519ce9c3deaa0f488ac56ea12000200000001b4ac666e5203231dd64a46b34cfd011a5936db53255660eaaae556db6289bb4601000000fdfd00004730440220632ccac4e480f6b911e298ed5e609db9d72c6eda9efa387cb26b5e9ef700163a02203edc214365c311dd7d19569360df806794eb9c2274469105b2bf338f7143a58141483045022100ca577f10fbfd29bca371c557bad428b01ae77f7914db285b61c0b499c5ff4b3d022001767845813496ded9b80a21b60b622219e0a08f3a92df0805047a8f3f12ca3b414c69522103472fe9fd7e726102894e84437e837b95f21913fd84804052228de77eae2a07bb2103203cab654b45e67c748e5adc91070fb5a166ff51378949d256808476c8e96bb021029fd0b61c762122b1a7e7c2f1fce53e6be52a0d486ec000635e757696a75120ca53aeffffffff01d6b02d00000000001976a91409fed3e08e624b23dbbacc77f7b2a39998351a6888ac000000000100000001074065abfdb5251f7fbb04c8a2700c1d1a497d07af8f0fff048535483418cd34010000006b483045022100eef073308d9a2e3031f2ae18511ffbe4ea84174036c7716b540c57b55268ee1d0220433acc4c47adeb89f3fd64163b22e61e3379f99fb75aa053c01ac020504fb864412103579c40a982ea207d7c8e99a4ad401ab17db47d8a24f2c63cc82a328a5d23d63bffffffff029c040200000000001976a914fad6c38dca5b36b443c2cc49389c3e1c7556354488acfdc40200000000001976a914b7e34815d2d9fc710cb603873f8c21b66033917588ac000000000100000001a37a930deb7dc18970d56be44165b8f58ffdad9c02519f261a8f5d8e311235de010000006a47304402203acfa68bfb3125cac57cb1b8e6483ef9ac901889cfc3da04893549ed8c1ddee102203b1d702161d9266707e4f9a026c84afd144d5fe28dfe5f2026ab2abc317b717a4121031872714bba791e1f80a604ec0fb170c6bb0110c509cbd35c7e92568f47a922b3ffffffff0280969800000000001976a914a8a6a3ed17b4a75bf8045fa9921771cb51bc948b88ac007e5603000000001976a9143769137f82fb4d8d1f8cb3c799f26139760d09ff88ac0000000001000000013ad31893160296f0a24fbbddb2f1f1bc5a6cec247158d1fe37c95289b22c480b000000006a4730440220364e2f5cdbd70453df3218532039acd2b6954b40db565f4657c8b4a4062e08f00220240022d4e2129e8847c835b1d61047a527b9c8d477020bbe9c5cfdc661e8b21d412102b3691c3d09206dd5a3fd9b97fc87904b859ad3c63d67c1751d45135e5f4ae434ffffffff01561d0f00000000001976a91498a7c0c7781de807e59185c540032744eb4b7f2d88ac000000000200000001f7e703143b521d0bf653e07a1a28f5b0cb84a7dd797e5b66183e50e5aebc5bb4010000006a473044022024ececc22b6a47bac0c5cfca8008b9ba5de49c6424f3ebfa236696f38e6d6bf9022069cb594fa8be28fa35128c2c05c96408da27165d7dcc0ef776cc838b858fed45412102b46e6d35aeae03348578220d21cb182e36599fa393a3150886c37ec16a10c58cfeffffff0240420f00000000001976a914f43c36964b237d6bc8e3165c551980059bdd75e888ac40f82200000000001976a914384b7137cc464a632961c74bd077e0ec5fb44a1888ac56ea12000200000008349c1ef994e931d4da1f545d2e578f898ddf457392c5485dc75378de8f36bef4010000006a4730440220351f1566e3ef02e900942103c60cba5a768cd710d3d1afbc75406099ad2d9e4702206e0f639a9991c7afb2136fb2e437629103ad0989898d1c90078ded5f08f5cb3341210303ae341929bdb242226a9a8c15cdbed5b89fa286842714d8be7e3f16c63abe11feffffff4ae685c8efc7f090e75b80f1b705d7bf5fa6dbbcf88c5f5cf2dc0678a9646fb4000000006b483045022100b8dae1825b0d0ccbe212e8da6767ea049bad9acfc737e5c5ef3dc5eeef6d313c02207e4c669956f871a4a5f71903bf38a8c587b81940943682364b11fb1cd9c078d7412103c9bd0064d2759628c1f6e5ad9d6345a5bce64dc4f4bb0675162f77acd557e4e2feffffff1ac21ded05387165cb7d0d95e2036a82f79a314575f065407e0c32a6b24b2f1d010000006b483045022100ef4a9469a5b3dbc0f03e8d8c5f254ad86f2c1e92e75a5ee737c3b3186b5edd95022076abcdfa976c3c78d2b196fb79699057248fad6d3d5e782524b85d84704394cc412103882df93f092501520bb36206703dadb65b25a3fbd0323c690dc8e72f5ee4a770feffffffea6905abb313a2aa3f6c8a056294abe06774dbf75688b03b96b8a2132aaf0cbf010000006b483045022100e4ab9dd0a75bc76c6c2cf549fb37c5577bad7f58953a7103abe4a77a95b873c10220545aa0c2b2869d444fb99d237549d6ac270c711d60788a6463ef4fee63ebd8fc4121031adea1da6e87b0771ea8c2a4723127d8cc9328b0594d159570ebe97b1e021c9efeffffff8c9a7a668dad3766f953d9779861f9c007b0a06f6ea2afbf8ab30137f34300fa000000006a47304402207253f724d891f5e1e66ec0c8084ade910a52257a1257933c23bd1b4da862e33a0220363df96e31dffa0a599b56c5049519a4d8ed34e96dc1fefecfd2bc31fc6d79d9412103186a4fc8445b3b437587c71f00fc9da7a267c0a38915fcf567528e310a73c0bdfeffffff82445d5b10b84b5256ef028615465e2d139c45584884c06e68bc38930d826e72010000006a47304402204846adc41599336307a087d4fa779a059ffe12c69456c82fa4b03942c901284002203e5f0c5e72b9ded7f48b4d22cbdb39390bea33003d46d8b4652c8ede1f13b3e54121031adea1da6e87b0771ea8c2a4723127d8cc9328b0594d159570ebe97b1e021c9efeffffffb8816c2c3b95aa8126f6d2d04798632b3167e6e2144d5f4e84cfb29e9d6f442d010000006a473044022078b1aff9a4ed3452f782db38341d846edd295f9a907c7373519408fb33eeb3240220578da5e91ec0c82604982b09cbd1f44e28260fcd640bcc55f086ce296ef32ef7412103c9bd0064d2759628c1f6e5ad9d6345a5bce64dc4f4bb0675162f77acd557e4e2feffffff70628ac9b2814f99fe4cd5f67a76047af533774ae90331fa8cb68e4dcbff1cb0010000006b483045022100cd88592589ab3bbd6e23920770a067a37ffbff3a31238167731377f11903676202202cb1c019365870dad3113abb3b0bc68ab9e65d9d60592f3315ffa444dfd88be741210393bd44ad6ed9295bf408e01bcdbdf6e4e8fd4a573ad20f37e54ff6e9b1596028feffffff027f766c02000000001976a9149f96c6e6c3aabf438eef5c589c47fa4b4f96592a88ac1c3d0f00000000001976a914e2ffd7cf2fe9468512878196d1b48fee9e9d003288ac56ea1200" - -var blockTxs = []string{ - "f12d490ad439ff37c91e9ec5ecd5440c2d4a96653f2668402c5ebacc6d07dcf8", - "0e78e3276bd59dd403306334ab05b2d58167b4cf04dbb94ae76dc189db5bf3df", - "9eeba85181725993afc6a89e2e98c07e12bbd9c732b851af448eb6055d8d8ba7", - "045f898538c5b9a99a4bf21c8e06aa7279caacdf7616994b7d4f0ed39637dff7", - "8614ae1addce0983f8b1bb2e6139fca4e7aa2d4f57f28ce1145bd1103c75a307", - "1d10b63e6d336b19ce7f7a867639b52b42be7e63ea53a86e5c7b101eb8f5bf59", - "1cbb193374d455ad09f1ae4486418dbbd65435ac14b1b8733897976bd776478b", - "722d99abace73265477b42849c86f9a8460a07aef7497187db24cffb4b27c856", - "a856b35655852ec5d698561633f997b945ee03d57a7b60e3c86eaabdd3a90054", - "e82cdbb67f6c23c72d0273bdd976697d5bfc4b2373e637f4eeb5211134b84bd6", - "efd3295c37cd3988f16efc09d083dbbc27f5c0074b9ea0dffd4f8540b36dd02c", - "b955bc3e800aa6d72c1a9eb9ce4a513f409ec923c31e30075f58336c830040a8", - "9730ec3e10e5a3bf358e533a497e75f44aceaf28da8248534326e5d7dac0d048", - "a90df75c045e638a0c00902d35c9c72592d0e76ac0fa34fba6aad749c5aded21", - "0e21dd654596cac9f579e21a549a533d1be7319470fcf8f920a35d64cf020d1f", -} - -var txDetails map[string]*bchain.Tx +var rpcTest *rpc.Test func init() { - var ( - addr1, addr2, addr3, addr4 bchain.Address - err error - ) - addr1, err = newBCashAddress("bchtest:pzkfpmv9zry6w3zmzp8azcprg8wzlzgdz5rta4dd0e", CashAddr) - if err == nil { - addr2, err = newBCashAddress("bchtest:qplha5t7wxhugzl2exudpv8m2de3zcfnnsaswsdmkt", CashAddr) - } - if err == nil { - addr3, err = newBCashAddress("bchtest:qz0ed3hxcw4t7suwaaw938z8lf95l9je9gg4grt7yx", CashAddr) - } - if err == nil { - addr4, err = newBCashAddress("bchtest:qr30l4709l55dpgjs7qed5d53lhfa8gqxgds6vr54u", CashAddr) - } + t, err := rpc.NewTest("bch", getRPCClient) if err != nil { panic(err) } - - txDetails = map[string]*bchain.Tx{ - "9eeba85181725993afc6a89e2e98c07e12bbd9c732b851af448eb6055d8d8ba7": &bchain.Tx{ - Hex: "0200000001b2c673aede02a4054a8c23e456e581d684f47dadb54083317d6152949d55d94e010000006b483045022100f31a23984a44f485a570a102899e3a25cdf6d1234259e602dbe61f2c3e77e490022069a6a7b013452bd66ed3c11aba22a64559134cd1af3d283730a9b7fb33631cca412103cb05918b81d36c387c791d2accfaefead287a4a30427387fb1095fc0c363ef8efeffffff0200c2eb0b0000000017a914ac90ed8510c9a7445b104fd1602341dc2f890d15878906e1e1160000001976a9147f7ed17e71afc40beac9b8d0b0fb53731161339c88ac56ea1200", - Blocktime: 1528796166, - Time: 1528796166, - Txid: "9eeba85181725993afc6a89e2e98c07e12bbd9c732b851af448eb6055d8d8ba7", - LockTime: 1239638, - Vin: []bchain.Vin{ - { - ScriptSig: bchain.ScriptSig{ - Hex: "483045022100f31a23984a44f485a570a102899e3a25cdf6d1234259e602dbe61f2c3e77e490022069a6a7b013452bd66ed3c11aba22a64559134cd1af3d283730a9b7fb33631cca412103cb05918b81d36c387c791d2accfaefead287a4a30427387fb1095fc0c363ef8e", - }, - Txid: "4ed9559d9452617d318340b5ad7df484d681e556e4238c4a05a402deae73c6b2", - Vout: 1, - Sequence: 4294967294, - }, - }, - Vout: []bchain.Vout{ - { - Value: 2.0, - N: 0, - ScriptPubKey: bchain.ScriptPubKey{ - Hex: "a914ac90ed8510c9a7445b104fd1602341dc2f890d1587", - Addresses: []string{ - "bchtest:pzkfpmv9zry6w3zmzp8azcprg8wzlzgdz5rta4dd0e", - }, - }, - Address: addr1, - }, - { - Value: 982.78901385, - N: 1, - ScriptPubKey: bchain.ScriptPubKey{ - Hex: "76a9147f7ed17e71afc40beac9b8d0b0fb53731161339c88ac", - Addresses: []string{ - "bchtest:qplha5t7wxhugzl2exudpv8m2de3zcfnnsaswsdmkt", - }, - }, - Address: addr2, - }, - }, - }, - "0e21dd654596cac9f579e21a549a533d1be7319470fcf8f920a35d64cf020d1f": &bchain.Tx{ - Hex: "0200000008349c1ef994e931d4da1f545d2e578f898ddf457392c5485dc75378de8f36bef4010000006a4730440220351f1566e3ef02e900942103c60cba5a768cd710d3d1afbc75406099ad2d9e4702206e0f639a9991c7afb2136fb2e437629103ad0989898d1c90078ded5f08f5cb3341210303ae341929bdb242226a9a8c15cdbed5b89fa286842714d8be7e3f16c63abe11feffffff4ae685c8efc7f090e75b80f1b705d7bf5fa6dbbcf88c5f5cf2dc0678a9646fb4000000006b483045022100b8dae1825b0d0ccbe212e8da6767ea049bad9acfc737e5c5ef3dc5eeef6d313c02207e4c669956f871a4a5f71903bf38a8c587b81940943682364b11fb1cd9c078d7412103c9bd0064d2759628c1f6e5ad9d6345a5bce64dc4f4bb0675162f77acd557e4e2feffffff1ac21ded05387165cb7d0d95e2036a82f79a314575f065407e0c32a6b24b2f1d010000006b483045022100ef4a9469a5b3dbc0f03e8d8c5f254ad86f2c1e92e75a5ee737c3b3186b5edd95022076abcdfa976c3c78d2b196fb79699057248fad6d3d5e782524b85d84704394cc412103882df93f092501520bb36206703dadb65b25a3fbd0323c690dc8e72f5ee4a770feffffffea6905abb313a2aa3f6c8a056294abe06774dbf75688b03b96b8a2132aaf0cbf010000006b483045022100e4ab9dd0a75bc76c6c2cf549fb37c5577bad7f58953a7103abe4a77a95b873c10220545aa0c2b2869d444fb99d237549d6ac270c711d60788a6463ef4fee63ebd8fc4121031adea1da6e87b0771ea8c2a4723127d8cc9328b0594d159570ebe97b1e021c9efeffffff8c9a7a668dad3766f953d9779861f9c007b0a06f6ea2afbf8ab30137f34300fa000000006a47304402207253f724d891f5e1e66ec0c8084ade910a52257a1257933c23bd1b4da862e33a0220363df96e31dffa0a599b56c5049519a4d8ed34e96dc1fefecfd2bc31fc6d79d9412103186a4fc8445b3b437587c71f00fc9da7a267c0a38915fcf567528e310a73c0bdfeffffff82445d5b10b84b5256ef028615465e2d139c45584884c06e68bc38930d826e72010000006a47304402204846adc41599336307a087d4fa779a059ffe12c69456c82fa4b03942c901284002203e5f0c5e72b9ded7f48b4d22cbdb39390bea33003d46d8b4652c8ede1f13b3e54121031adea1da6e87b0771ea8c2a4723127d8cc9328b0594d159570ebe97b1e021c9efeffffffb8816c2c3b95aa8126f6d2d04798632b3167e6e2144d5f4e84cfb29e9d6f442d010000006a473044022078b1aff9a4ed3452f782db38341d846edd295f9a907c7373519408fb33eeb3240220578da5e91ec0c82604982b09cbd1f44e28260fcd640bcc55f086ce296ef32ef7412103c9bd0064d2759628c1f6e5ad9d6345a5bce64dc4f4bb0675162f77acd557e4e2feffffff70628ac9b2814f99fe4cd5f67a76047af533774ae90331fa8cb68e4dcbff1cb0010000006b483045022100cd88592589ab3bbd6e23920770a067a37ffbff3a31238167731377f11903676202202cb1c019365870dad3113abb3b0bc68ab9e65d9d60592f3315ffa444dfd88be741210393bd44ad6ed9295bf408e01bcdbdf6e4e8fd4a573ad20f37e54ff6e9b1596028feffffff027f766c02000000001976a9149f96c6e6c3aabf438eef5c589c47fa4b4f96592a88ac1c3d0f00000000001976a914e2ffd7cf2fe9468512878196d1b48fee9e9d003288ac56ea1200", - Blocktime: 1528796166, - Time: 1528796166, - Txid: "0e21dd654596cac9f579e21a549a533d1be7319470fcf8f920a35d64cf020d1f", - LockTime: 1239638, - Vin: []bchain.Vin{ - { - ScriptSig: bchain.ScriptSig{ - Hex: "4730440220351f1566e3ef02e900942103c60cba5a768cd710d3d1afbc75406099ad2d9e4702206e0f639a9991c7afb2136fb2e437629103ad0989898d1c90078ded5f08f5cb3341210303ae341929bdb242226a9a8c15cdbed5b89fa286842714d8be7e3f16c63abe11", - }, - Txid: "f4be368fde7853c75d48c5927345df8d898f572e5d541fdad431e994f91e9c34", - Vout: 1, - Sequence: 4294967294, - }, - { - ScriptSig: bchain.ScriptSig{ - Hex: "483045022100b8dae1825b0d0ccbe212e8da6767ea049bad9acfc737e5c5ef3dc5eeef6d313c02207e4c669956f871a4a5f71903bf38a8c587b81940943682364b11fb1cd9c078d7412103c9bd0064d2759628c1f6e5ad9d6345a5bce64dc4f4bb0675162f77acd557e4e2", - }, - Txid: "b46f64a97806dcf25c5f8cf8bcdba65fbfd705b7f1805be790f0c7efc885e64a", - Vout: 0, - Sequence: 4294967294, - }, - { - ScriptSig: bchain.ScriptSig{ - Hex: "483045022100ef4a9469a5b3dbc0f03e8d8c5f254ad86f2c1e92e75a5ee737c3b3186b5edd95022076abcdfa976c3c78d2b196fb79699057248fad6d3d5e782524b85d84704394cc412103882df93f092501520bb36206703dadb65b25a3fbd0323c690dc8e72f5ee4a770", - }, - Txid: "1d2f4bb2a6320c7e4065f07545319af7826a03e2950d7dcb65713805ed1dc21a", - Vout: 1, - Sequence: 4294967294, - }, - { - ScriptSig: bchain.ScriptSig{ - Hex: "483045022100e4ab9dd0a75bc76c6c2cf549fb37c5577bad7f58953a7103abe4a77a95b873c10220545aa0c2b2869d444fb99d237549d6ac270c711d60788a6463ef4fee63ebd8fc4121031adea1da6e87b0771ea8c2a4723127d8cc9328b0594d159570ebe97b1e021c9e", - }, - Txid: "bf0caf2a13a2b8963bb08856f7db7467e0ab9462058a6c3faaa213b3ab0569ea", - Vout: 1, - Sequence: 4294967294, - }, - { - ScriptSig: bchain.ScriptSig{ - Hex: "47304402207253f724d891f5e1e66ec0c8084ade910a52257a1257933c23bd1b4da862e33a0220363df96e31dffa0a599b56c5049519a4d8ed34e96dc1fefecfd2bc31fc6d79d9412103186a4fc8445b3b437587c71f00fc9da7a267c0a38915fcf567528e310a73c0bd", - }, - Txid: "fa0043f33701b38abfafa26e6fa0b007c0f9619877d953f96637ad8d667a9a8c", - Vout: 0, - Sequence: 4294967294, - }, - { - ScriptSig: bchain.ScriptSig{ - Hex: "47304402204846adc41599336307a087d4fa779a059ffe12c69456c82fa4b03942c901284002203e5f0c5e72b9ded7f48b4d22cbdb39390bea33003d46d8b4652c8ede1f13b3e54121031adea1da6e87b0771ea8c2a4723127d8cc9328b0594d159570ebe97b1e021c9e", - }, - Txid: "726e820d9338bc686ec0844858459c132d5e46158602ef56524bb8105b5d4482", - Vout: 1, - Sequence: 4294967294, - }, - { - ScriptSig: bchain.ScriptSig{ - Hex: "473044022078b1aff9a4ed3452f782db38341d846edd295f9a907c7373519408fb33eeb3240220578da5e91ec0c82604982b09cbd1f44e28260fcd640bcc55f086ce296ef32ef7412103c9bd0064d2759628c1f6e5ad9d6345a5bce64dc4f4bb0675162f77acd557e4e2", - }, - Txid: "2d446f9d9eb2cf844e5f4d14e2e667312b639847d0d2f62681aa953b2c6c81b8", - Vout: 1, - Sequence: 4294967294, - }, - { - ScriptSig: bchain.ScriptSig{ - Hex: "483045022100cd88592589ab3bbd6e23920770a067a37ffbff3a31238167731377f11903676202202cb1c019365870dad3113abb3b0bc68ab9e65d9d60592f3315ffa444dfd88be741210393bd44ad6ed9295bf408e01bcdbdf6e4e8fd4a573ad20f37e54ff6e9b1596028", - }, - Txid: "b01cffcb4d8eb68cfa3103e94a7733f57a04767af6d54cfe994f81b2c98a6270", - Vout: 1, - Sequence: 4294967294, - }, - }, - Vout: []bchain.Vout{ - { - Value: 0.40662655, - N: 0, - ScriptPubKey: bchain.ScriptPubKey{ - Hex: "76a9149f96c6e6c3aabf438eef5c589c47fa4b4f96592a88ac", - Addresses: []string{ - "bchtest:qz0ed3hxcw4t7suwaaw938z8lf95l9je9gg4grt7yx", - }, - }, - Address: addr3, - }, - { - Value: 0.00998684, - N: 1, - ScriptPubKey: bchain.ScriptPubKey{ - Hex: "76a914e2ffd7cf2fe9468512878196d1b48fee9e9d003288ac", - Addresses: []string{ - "bchtest:qr30l4709l55dpgjs7qed5d53lhfa8gqxgds6vr54u", - }, - }, - Address: addr4, - }, - }, - }, - } + rpcTest = t } func TestBCashRPC_GetBlockHash(t *testing.T) { - cli, err := getRPCClient() - if err != nil { - t.Fatal(err) - } - - hash, err := cli.GetBlockHash(blockHeight) - if err != nil { - t.Error(err) - return - } - - if hash != blockHash { - t.Errorf("GetBlockHash() got %q, want %q", hash, blockHash) - } -} - -func TestBCashRPC_GetBlockRaw(t *testing.T) { - cli, err := getRPCClient() - if err != nil { - t.Fatal(err) - } - - d, err := cli.GetBlockRaw(blockHash) - if err != nil { - t.Error(err) - return - } - - blk := hex.EncodeToString(d) - - if blk != blockHex { - t.Errorf("GetBlockRaw() got %q, want %q", blk, blockHex) - } + rpcTest.TestGetBlockHash(t) } func TestBCashRPC_GetBlock(t *testing.T) { - cli, err := getRPCClient() - if err != nil { - t.Fatal(err) - } - - blk, err := cli.GetBlock(blockHash, 0) - if err != nil { - t.Error(err) - return - } - - if len(blk.Txs) != len(blockTxs) { - t.Errorf("GetBlock() number of transactions: got %d, want %d", len(blk.Txs), len(blockTxs)) - } - - for ti, tx := range blk.Txs { - if tx.Txid != blockTxs[ti] { - t.Errorf("GetBlock() transaction %d: got %s, want %s", ti, tx.Txid, blockTxs[ti]) - } - } - + rpcTest.TestGetBlock(t) } func TestBCashRPC_GetTransaction(t *testing.T) { - cli, err := getRPCClient() - if err != nil { - t.Fatal(err) - } - - for txid, want := range txDetails { - got, err := cli.GetTransaction(txid) - if err != nil { - t.Error(err) - return - } - - // Confirmations is variable field, we just check if is set and reset it - if got.Confirmations > 0 { - got.Confirmations = 0 - } else { - t.Errorf("GetTransaction() has empty Confirmations field") - continue - } - - if !reflect.DeepEqual(got, want) { - t.Errorf("GetTransaction() got %v, want %v", got, want) - } - } + rpcTest.TestGetTransaction(t) } diff --git a/bchain/coins/btc/bitcoinparser.go b/bchain/coins/btc/bitcoinparser.go index eab5891d..41c52759 100644 --- a/bchain/coins/btc/bitcoinparser.go +++ b/bchain/coins/btc/bitcoinparser.go @@ -20,8 +20,8 @@ type OutputScriptToAddressesFunc func(script []byte, params *chaincfg.Params) ([ // BitcoinParser handle type BitcoinParser struct { *bchain.BaseParser - Params *chaincfg.Params - OutputScriptToAddresses OutputScriptToAddressesFunc + Params *chaincfg.Params + OutputScriptToAddressesFunc OutputScriptToAddressesFunc } // NewBitcoinParser returns new BitcoinParser instance @@ -72,6 +72,11 @@ func (p *BitcoinParser) AddressToOutputScript(address string) ([]byte, error) { return script, nil } +// OutputScriptToAddresses converts ScriptPubKey to bitcoin addresses +func (p *BitcoinParser) OutputScriptToAddresses(script []byte) ([]string, error) { + return p.OutputScriptToAddressesFunc(script, p.Params) +} + // outputScriptToAddresses converts ScriptPubKey to bitcoin addresses func outputScriptToAddresses(script []byte, params *chaincfg.Params) ([]string, error) { _, addresses, _, err := txscript.ExtractPkScriptAddrs(script, params) @@ -110,7 +115,7 @@ func (p *BitcoinParser) TxFromMsgTx(t *wire.MsgTx, parseAddresses bool) bchain.T for i, out := range t.TxOut { addrs := []string{} if parseAddresses { - addrs, _ = p.OutputScriptToAddresses(out.PkScript, p.Params) + addrs, _ = p.OutputScriptToAddresses(out.PkScript) } s := bchain.ScriptPubKey{ Hex: hex.EncodeToString(out.PkScript), diff --git a/bchain/tests/rpc/config.json b/bchain/tests/rpc/config.json new file mode 100644 index 00000000..97345646 --- /dev/null +++ b/bchain/tests/rpc/config.json @@ -0,0 +1,27 @@ +{ + "bch": { + "url": "http://localhost:18031", + "user": "rpc", + "pass": "rpc" + }, + "btc": { + "url": "http://localhost:18030", + "user": "rpc", + "pass": "rpc" + }, + "dash": { + "url": "http://localhost:18033", + "user": "rpc", + "pass": "rpc" + }, + "eth": { + "url": "ws://localhost:18036", + "user": null, + "pass": null + }, + "zec": { + "url": "http://localhost:18032", + "user": "rpc", + "pass": "rpc" + } +} diff --git a/bchain/tests/rpc/data.go b/bchain/tests/rpc/data.go new file mode 100644 index 00000000..2d75dc59 --- /dev/null +++ b/bchain/tests/rpc/data.go @@ -0,0 +1,96 @@ +// +build integration + +package rpc + +import ( + "encoding/json" + "errors" + "fmt" + "io/ioutil" + "path/filepath" + "strings" +) + +func joinPathsWithCommonElement(p1, p2 string) (string, bool) { + idx := strings.IndexRune(p2, filepath.Separator) + if idx <= 0 { + return "", false + } + p2root := p2[:idx] + idx = strings.LastIndex(p1, p2root) + if idx < 0 { + return "", false + } + prefix := p1[:idx] + return filepath.Join(prefix, p2), true +} + +func readDataFile(dir, relDir, filename string) ([]byte, error) { + var err error + dir, err = filepath.Abs(dir) + if err == nil { + dir, err = filepath.EvalSymlinks(dir) + } + if err != nil { + return nil, err + } + path, ok := joinPathsWithCommonElement(dir, relDir) + if !ok { + return nil, errors.New("Path not found") + } + path = filepath.Join(path, filename) + return ioutil.ReadFile(path) +} + +var testConfigRegistry map[string]*TestConfig + +func LoadTestConfig(coin string) (*TestConfig, error) { + if testConfigRegistry == nil { + b, err := readDataFile(".", "bchain/tests/rpc", "config.json") + if err != nil { + return nil, err + } + var v map[string]*TestConfig + err = json.Unmarshal(b, &v) + if err != nil { + return nil, err + } + testConfigRegistry = v + } + c, found := testConfigRegistry[coin] + if !found { + return nil, errors.New("Test config not found") + } + return c, nil +} + +func LoadRPCConfig(coin string) (json.RawMessage, error) { + t := `{ + "coin_name": "%s", + "rpcURL": "%s", + "rpcUser": "%s", + "rpcPass": "%s", + "rpcTimeout": 25, + "parse": true + }` + + c, err := LoadTestConfig(coin) + if err != nil { + return json.RawMessage{}, err + } + + return json.RawMessage(fmt.Sprintf(t, coin, c.URL, c.User, c.Pass)), nil +} + +func LoadTestData(coin string) (*TestData, error) { + b, err := readDataFile(".", "bchain/tests/rpc/testdata", coin+".json") + if err != nil { + return nil, err + } + var v TestData + err = json.Unmarshal(b, &v) + if err != nil { + return nil, err + } + return &v, nil +} diff --git a/bchain/tests/rpc/rpc.go b/bchain/tests/rpc/rpc.go new file mode 100644 index 00000000..0a486963 --- /dev/null +++ b/bchain/tests/rpc/rpc.go @@ -0,0 +1,126 @@ +// +build integration + +package rpc + +import ( + "blockbook/bchain" + "encoding/json" + "reflect" + "testing" +) + +type TestConfig struct { + URL string `json:"url"` + User string `json:"user"` + Pass string `json:"pass"` +} + +type TestData struct { + BlockHeight uint32 `json:"blockHeight"` + BlockHash string `json:"blockHash"` + BlockHex string `json:"blockHex"` + BlockTxs []string `json:"blockTxs"` + TxDetails map[string]*bchain.Tx `json:"txDetails"` +} + +type Test struct { + Client bchain.BlockChain + TestData *TestData +} + +type TestChainFactoryFunc func(json.RawMessage) (bchain.BlockChain, error) + +func NewTest(coin string, factory TestChainFactoryFunc) (*Test, error) { + cfg, err := LoadRPCConfig(coin) + if err != nil { + return nil, err + } + cli, err := factory(cfg) + if err != nil { + return nil, err + } + td, err := LoadTestData(coin) + if err != nil { + return nil, err + } + + if td.TxDetails != nil { + parser := cli.GetChainParser() + + for _, tx := range td.TxDetails { + err := setTxAddresses(parser, tx) + if err != nil { + return nil, err + } + } + } + + return &Test{Client: cli, TestData: td}, nil +} + +func setTxAddresses(parser bchain.BlockChainParser, tx *bchain.Tx) error { + // pack and unpack transaction in order to get addresses decoded - ugly but works + var tmp *bchain.Tx + b, err := parser.PackTx(tx, 0, 0) + if err == nil { + tmp, _, err = parser.UnpackTx(b) + if err == nil { + for i := 0; i < len(tx.Vout); i++ { + tx.Vout[i].ScriptPubKey.Addresses = tmp.Vout[i].ScriptPubKey.Addresses + tx.Vout[i].Address = tmp.Vout[i].Address + } + } + } + return err +} +func (rt *Test) TestGetBlockHash(t *testing.T) { + hash, err := rt.Client.GetBlockHash(rt.TestData.BlockHeight) + if err != nil { + t.Error(err) + return + } + + if hash != rt.TestData.BlockHash { + t.Errorf("GetBlockHash() got %q, want %q", hash, rt.TestData.BlockHash) + } +} + +func (rt *Test) TestGetBlock(t *testing.T) { + blk, err := rt.Client.GetBlock(rt.TestData.BlockHash, 0) + if err != nil { + t.Error(err) + return + } + + if len(blk.Txs) != len(rt.TestData.BlockTxs) { + t.Errorf("GetBlock() number of transactions: got %d, want %d", len(blk.Txs), len(rt.TestData.BlockTxs)) + } + + for ti, tx := range blk.Txs { + if tx.Txid != rt.TestData.BlockTxs[ti] { + t.Errorf("GetBlock() transaction %d: got %s, want %s", ti, tx.Txid, rt.TestData.BlockTxs[ti]) + } + } + +} +func (rt *Test) TestGetTransaction(t *testing.T) { + for txid, want := range rt.TestData.TxDetails { + got, err := rt.Client.GetTransaction(txid) + if err != nil { + t.Error(err) + return + } + + // Confirmations is variable field, we just check if is set and reset it + if got.Confirmations > 0 { + got.Confirmations = 0 + } else { + t.Errorf("GetTransaction() has empty Confirmations field") + continue + } + + if !reflect.DeepEqual(got, want) { + t.Errorf("GetTransaction() got %v, want %v", got, want) + } + } +} diff --git a/bchain/tests/rpc/testdata/bch.json b/bchain/tests/rpc/testdata/bch.json new file mode 100644 index 00000000..c59acf85 --- /dev/null +++ b/bchain/tests/rpc/testdata/bch.json @@ -0,0 +1,146 @@ +{ + "blockHeight": 1239639, + "blockHash": "0000000075dd9708c23f5830de27c5d644983bb877c575c52926f19be7d80fe2", + "blockHex": "00000020fb79eebaff373687fdd612fd8ffb1717b866f7a7748cef7d6994198000000000bbaec06df359e98bd122726c9f178f4fdaa0fb59b3b86d18e465d53acc33bfda06941f5bffff001d7a6681650f01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0a0357ea12055374617368ffffffff0157966009000000001976a914014dc11b35cafe7605b4c1798a5b86efd788cff488ac0000000002000000014071f84a20eaeac1ba417ba63257087999a1c6401b94cdcf898079036aa00949000000006a4730440220600c88cf5f283d4b607253c1345e9d20bc4d67dc523070ad2f27f4ec337da44a02200f80a2dc8a0b501fb9c7fcb85851e05e83acbaf24b7a0cec5c1026c9cf004383412102e5e90f37c8a8f9ba15c3cce80f2f823bcc222063b7bc46e88ed7cd7d335d110afeffffff0200e1f5050000000017a914ac90ed8510c9a7445b104fd1602341dc2f890d1587795e27ea160000001976a91488f18e19e4a62fce9ab0db1cfb29cc22a058562588ac22ea12000200000001b2c673aede02a4054a8c23e456e581d684f47dadb54083317d6152949d55d94e010000006b483045022100f31a23984a44f485a570a102899e3a25cdf6d1234259e602dbe61f2c3e77e490022069a6a7b013452bd66ed3c11aba22a64559134cd1af3d283730a9b7fb33631cca412103cb05918b81d36c387c791d2accfaefead287a4a30427387fb1095fc0c363ef8efeffffff0200c2eb0b0000000017a914ac90ed8510c9a7445b104fd1602341dc2f890d15878906e1e1160000001976a9147f7ed17e71afc40beac9b8d0b0fb53731161339c88ac56ea1200020000000103365f2950d5d427beac98e2e5658cab90ce9b48350c62c5747dcb14d70f7602010000006b4830450221009acfe9bce502d2ad19d10c9278887f041e07a4f8277d1837733841ff6ea201cc022065a757b167b1b842211531b0b6ee891da19025e692dcb138add4738e8ad9524d412102a69b92783a38bc29c7f669818d922cf8566f41dbc8dd4992e72b69480a8766adfeffffff02b4b157fe160000001976a91414fba45042c5d32455a02e97f5e3c12874df267088ac00e1f505000000001976a9148c5d5ba49d1661f3c07261fe25ce6d849cd40d3c88ac56ea12000200000001768dcdaa8e733e9de87bd4762567e16e362746ff6752a393f5b62f9e1760209b000000006b483045022100df684fea9661ff797aa9e977d6b223e3cff4b661b1f49b61ae4590e48c0f1ebc0220635ebec87bd291b8263f0500797e2de573f94d7ee69dad63ce19add5abf273d5412103639049ceb22afb8c9070fe00562833a4e367c45c5c632daf75e81ea101cc6f2bfeffffff0298f7d3d1160000001976a914bbcd80aacaa6d8fe22bded7fec4746eb605dbf2388ac00e1f505000000001976a9146010d148212eabdec987af9568ed3c16bc8565c388ac56ea12000200000001e06d5b80b1dc384515b51accb247cfe74da3652c204758aeb48b9447e061d624000000006a47304402200252a79712e87e0212802e064dae51b0b93cc27642f6a521f84f522f9713f90702207234f37a4db14b0678d3301c67b7eaadde293394128c346c619aa2baeccfdf4b412103e8ec57f9d6f63d46ff1a83df3463048c5a1f77de7648da8d11d98347e79d260dfeffffff0230932c7f160000001976a91471707ab51d344b3996c4056a9f86659c8452592d88ac20bcbe00000000001976a914cd14f744df519aa04553b65c20a2fd0f7d653cc688ac56ea12000200000001d4d209bc5fb71b8d15a2a97846cec3cca73dc1d86ea66072a5478e59317017cc000000006a47304402207f6dbce56aa6548859bac719fb410859f366f190f63787b2a22339b1a1b338cf02204fee90094758a40e34726018a43b23e9789f1dcfc2da2515684d409c057818f741210372c26fba05c5bd542c1f8ff5bb2d2bebc26565bccd0731a4b6b7cd304eb50ca0feffffff028ecc1a4f160000001976a914e71a68a6fdf8badab6f8639dde10bdc436c4a40988ac00c2eb0b000000001976a914a28bc738fc7af8e0545edc40407cfb05077c60b888ac36ea120002000000013a047d9af4ecc4e7f8fdfded63af66f4e6a6e952f6ac95d905ea234b0a5152d3010000006a473044022028cd96dbaba2c72d36c3bdb5ec2ceff9520142ab045ddbd76732dd0a81147c1c0220394ab87587374ad48153def50abff43e410462456f04147a8b7af141274fa55c412102c01655518abdf62b4f6898d1ab9b90496cf97ee2ed9a4f949e695472fd45d1e0feffffff02ffad805f150000001976a9148c0c65371147f8f7e63e3ff1319be62a554dca9988ac00c2eb0b000000001976a9148c5d5ba49d1661f3c07261fe25ce6d849cd40d3c88ac56ea12000200000001ba548aa7f7d4342e4ba8ba4d0657b06778fb77d1258240be8f42f9f0415da359010000006b483045022100a42c83bf0bb95adc29f63b4c4d4831c0cbf8bb44f2a836db227be6f0208b2a550220746f3a9da3cec8308ff8f1907cdbd7b3d1c7462db5a54abfe68d207ffa159d53412103653ece38ad97d96f6782d5f8ea83a0bb861f69f4bad444c6bfbcac449666e7b4feffffff0240787d01000000001976a914cd14f744df519aa04553b65c20a2fd0f7d653cc688ac9a107ef2120000001976a914b3e12112e6c3614ecd980b76e519ce9c3deaa0f488ac56ea12000200000001b4ac666e5203231dd64a46b34cfd011a5936db53255660eaaae556db6289bb4601000000fdfd00004730440220632ccac4e480f6b911e298ed5e609db9d72c6eda9efa387cb26b5e9ef700163a02203edc214365c311dd7d19569360df806794eb9c2274469105b2bf338f7143a58141483045022100ca577f10fbfd29bca371c557bad428b01ae77f7914db285b61c0b499c5ff4b3d022001767845813496ded9b80a21b60b622219e0a08f3a92df0805047a8f3f12ca3b414c69522103472fe9fd7e726102894e84437e837b95f21913fd84804052228de77eae2a07bb2103203cab654b45e67c748e5adc91070fb5a166ff51378949d256808476c8e96bb021029fd0b61c762122b1a7e7c2f1fce53e6be52a0d486ec000635e757696a75120ca53aeffffffff01d6b02d00000000001976a91409fed3e08e624b23dbbacc77f7b2a39998351a6888ac000000000100000001074065abfdb5251f7fbb04c8a2700c1d1a497d07af8f0fff048535483418cd34010000006b483045022100eef073308d9a2e3031f2ae18511ffbe4ea84174036c7716b540c57b55268ee1d0220433acc4c47adeb89f3fd64163b22e61e3379f99fb75aa053c01ac020504fb864412103579c40a982ea207d7c8e99a4ad401ab17db47d8a24f2c63cc82a328a5d23d63bffffffff029c040200000000001976a914fad6c38dca5b36b443c2cc49389c3e1c7556354488acfdc40200000000001976a914b7e34815d2d9fc710cb603873f8c21b66033917588ac000000000100000001a37a930deb7dc18970d56be44165b8f58ffdad9c02519f261a8f5d8e311235de010000006a47304402203acfa68bfb3125cac57cb1b8e6483ef9ac901889cfc3da04893549ed8c1ddee102203b1d702161d9266707e4f9a026c84afd144d5fe28dfe5f2026ab2abc317b717a4121031872714bba791e1f80a604ec0fb170c6bb0110c509cbd35c7e92568f47a922b3ffffffff0280969800000000001976a914a8a6a3ed17b4a75bf8045fa9921771cb51bc948b88ac007e5603000000001976a9143769137f82fb4d8d1f8cb3c799f26139760d09ff88ac0000000001000000013ad31893160296f0a24fbbddb2f1f1bc5a6cec247158d1fe37c95289b22c480b000000006a4730440220364e2f5cdbd70453df3218532039acd2b6954b40db565f4657c8b4a4062e08f00220240022d4e2129e8847c835b1d61047a527b9c8d477020bbe9c5cfdc661e8b21d412102b3691c3d09206dd5a3fd9b97fc87904b859ad3c63d67c1751d45135e5f4ae434ffffffff01561d0f00000000001976a91498a7c0c7781de807e59185c540032744eb4b7f2d88ac000000000200000001f7e703143b521d0bf653e07a1a28f5b0cb84a7dd797e5b66183e50e5aebc5bb4010000006a473044022024ececc22b6a47bac0c5cfca8008b9ba5de49c6424f3ebfa236696f38e6d6bf9022069cb594fa8be28fa35128c2c05c96408da27165d7dcc0ef776cc838b858fed45412102b46e6d35aeae03348578220d21cb182e36599fa393a3150886c37ec16a10c58cfeffffff0240420f00000000001976a914f43c36964b237d6bc8e3165c551980059bdd75e888ac40f82200000000001976a914384b7137cc464a632961c74bd077e0ec5fb44a1888ac56ea12000200000008349c1ef994e931d4da1f545d2e578f898ddf457392c5485dc75378de8f36bef4010000006a4730440220351f1566e3ef02e900942103c60cba5a768cd710d3d1afbc75406099ad2d9e4702206e0f639a9991c7afb2136fb2e437629103ad0989898d1c90078ded5f08f5cb3341210303ae341929bdb242226a9a8c15cdbed5b89fa286842714d8be7e3f16c63abe11feffffff4ae685c8efc7f090e75b80f1b705d7bf5fa6dbbcf88c5f5cf2dc0678a9646fb4000000006b483045022100b8dae1825b0d0ccbe212e8da6767ea049bad9acfc737e5c5ef3dc5eeef6d313c02207e4c669956f871a4a5f71903bf38a8c587b81940943682364b11fb1cd9c078d7412103c9bd0064d2759628c1f6e5ad9d6345a5bce64dc4f4bb0675162f77acd557e4e2feffffff1ac21ded05387165cb7d0d95e2036a82f79a314575f065407e0c32a6b24b2f1d010000006b483045022100ef4a9469a5b3dbc0f03e8d8c5f254ad86f2c1e92e75a5ee737c3b3186b5edd95022076abcdfa976c3c78d2b196fb79699057248fad6d3d5e782524b85d84704394cc412103882df93f092501520bb36206703dadb65b25a3fbd0323c690dc8e72f5ee4a770feffffffea6905abb313a2aa3f6c8a056294abe06774dbf75688b03b96b8a2132aaf0cbf010000006b483045022100e4ab9dd0a75bc76c6c2cf549fb37c5577bad7f58953a7103abe4a77a95b873c10220545aa0c2b2869d444fb99d237549d6ac270c711d60788a6463ef4fee63ebd8fc4121031adea1da6e87b0771ea8c2a4723127d8cc9328b0594d159570ebe97b1e021c9efeffffff8c9a7a668dad3766f953d9779861f9c007b0a06f6ea2afbf8ab30137f34300fa000000006a47304402207253f724d891f5e1e66ec0c8084ade910a52257a1257933c23bd1b4da862e33a0220363df96e31dffa0a599b56c5049519a4d8ed34e96dc1fefecfd2bc31fc6d79d9412103186a4fc8445b3b437587c71f00fc9da7a267c0a38915fcf567528e310a73c0bdfeffffff82445d5b10b84b5256ef028615465e2d139c45584884c06e68bc38930d826e72010000006a47304402204846adc41599336307a087d4fa779a059ffe12c69456c82fa4b03942c901284002203e5f0c5e72b9ded7f48b4d22cbdb39390bea33003d46d8b4652c8ede1f13b3e54121031adea1da6e87b0771ea8c2a4723127d8cc9328b0594d159570ebe97b1e021c9efeffffffb8816c2c3b95aa8126f6d2d04798632b3167e6e2144d5f4e84cfb29e9d6f442d010000006a473044022078b1aff9a4ed3452f782db38341d846edd295f9a907c7373519408fb33eeb3240220578da5e91ec0c82604982b09cbd1f44e28260fcd640bcc55f086ce296ef32ef7412103c9bd0064d2759628c1f6e5ad9d6345a5bce64dc4f4bb0675162f77acd557e4e2feffffff70628ac9b2814f99fe4cd5f67a76047af533774ae90331fa8cb68e4dcbff1cb0010000006b483045022100cd88592589ab3bbd6e23920770a067a37ffbff3a31238167731377f11903676202202cb1c019365870dad3113abb3b0bc68ab9e65d9d60592f3315ffa444dfd88be741210393bd44ad6ed9295bf408e01bcdbdf6e4e8fd4a573ad20f37e54ff6e9b1596028feffffff027f766c02000000001976a9149f96c6e6c3aabf438eef5c589c47fa4b4f96592a88ac1c3d0f00000000001976a914e2ffd7cf2fe9468512878196d1b48fee9e9d003288ac56ea1200", + "blockTxs": [ + "f12d490ad439ff37c91e9ec5ecd5440c2d4a96653f2668402c5ebacc6d07dcf8", + "0e78e3276bd59dd403306334ab05b2d58167b4cf04dbb94ae76dc189db5bf3df", + "9eeba85181725993afc6a89e2e98c07e12bbd9c732b851af448eb6055d8d8ba7", + "045f898538c5b9a99a4bf21c8e06aa7279caacdf7616994b7d4f0ed39637dff7", + "8614ae1addce0983f8b1bb2e6139fca4e7aa2d4f57f28ce1145bd1103c75a307", + "1d10b63e6d336b19ce7f7a867639b52b42be7e63ea53a86e5c7b101eb8f5bf59", + "1cbb193374d455ad09f1ae4486418dbbd65435ac14b1b8733897976bd776478b", + "722d99abace73265477b42849c86f9a8460a07aef7497187db24cffb4b27c856", + "a856b35655852ec5d698561633f997b945ee03d57a7b60e3c86eaabdd3a90054", + "e82cdbb67f6c23c72d0273bdd976697d5bfc4b2373e637f4eeb5211134b84bd6", + "efd3295c37cd3988f16efc09d083dbbc27f5c0074b9ea0dffd4f8540b36dd02c", + "b955bc3e800aa6d72c1a9eb9ce4a513f409ec923c31e30075f58336c830040a8", + "9730ec3e10e5a3bf358e533a497e75f44aceaf28da8248534326e5d7dac0d048", + "a90df75c045e638a0c00902d35c9c72592d0e76ac0fa34fba6aad749c5aded21", + "0e21dd654596cac9f579e21a549a533d1be7319470fcf8f920a35d64cf020d1f" + ], + "txDetails": { + "9eeba85181725993afc6a89e2e98c07e12bbd9c732b851af448eb6055d8d8ba7": { + "hex": "0200000001b2c673aede02a4054a8c23e456e581d684f47dadb54083317d6152949d55d94e010000006b483045022100f31a23984a44f485a570a102899e3a25cdf6d1234259e602dbe61f2c3e77e490022069a6a7b013452bd66ed3c11aba22a64559134cd1af3d283730a9b7fb33631cca412103cb05918b81d36c387c791d2accfaefead287a4a30427387fb1095fc0c363ef8efeffffff0200c2eb0b0000000017a914ac90ed8510c9a7445b104fd1602341dc2f890d15878906e1e1160000001976a9147f7ed17e71afc40beac9b8d0b0fb53731161339c88ac56ea1200", + "txid": "9eeba85181725993afc6a89e2e98c07e12bbd9c732b851af448eb6055d8d8ba7", + "blocktime":1528796166, + "time":1528796166, + "locktime": 1239638, + "vin": [ + { + "txid": "4ed9559d9452617d318340b5ad7df484d681e556e4238c4a05a402deae73c6b2", + "vout": 1, + "sequence": 4294967294, + "scriptSig": { + "hex": "483045022100f31a23984a44f485a570a102899e3a25cdf6d1234259e602dbe61f2c3e77e490022069a6a7b013452bd66ed3c11aba22a64559134cd1af3d283730a9b7fb33631cca412103cb05918b81d36c387c791d2accfaefead287a4a30427387fb1095fc0c363ef8e" + } + } + ], + "vout": [ + { + "value": 2.0, + "n": 0, + "scriptPubKey": { + "hex": "a914ac90ed8510c9a7445b104fd1602341dc2f890d1587" + } + }, + { + "value": 982.78901385, + "n": 1, + "scriptPubKey": { + "hex": "76a9147f7ed17e71afc40beac9b8d0b0fb53731161339c88ac" + } + } + ] + }, + "0e21dd654596cac9f579e21a549a533d1be7319470fcf8f920a35d64cf020d1f": { + "hex": "0200000008349c1ef994e931d4da1f545d2e578f898ddf457392c5485dc75378de8f36bef4010000006a4730440220351f1566e3ef02e900942103c60cba5a768cd710d3d1afbc75406099ad2d9e4702206e0f639a9991c7afb2136fb2e437629103ad0989898d1c90078ded5f08f5cb3341210303ae341929bdb242226a9a8c15cdbed5b89fa286842714d8be7e3f16c63abe11feffffff4ae685c8efc7f090e75b80f1b705d7bf5fa6dbbcf88c5f5cf2dc0678a9646fb4000000006b483045022100b8dae1825b0d0ccbe212e8da6767ea049bad9acfc737e5c5ef3dc5eeef6d313c02207e4c669956f871a4a5f71903bf38a8c587b81940943682364b11fb1cd9c078d7412103c9bd0064d2759628c1f6e5ad9d6345a5bce64dc4f4bb0675162f77acd557e4e2feffffff1ac21ded05387165cb7d0d95e2036a82f79a314575f065407e0c32a6b24b2f1d010000006b483045022100ef4a9469a5b3dbc0f03e8d8c5f254ad86f2c1e92e75a5ee737c3b3186b5edd95022076abcdfa976c3c78d2b196fb79699057248fad6d3d5e782524b85d84704394cc412103882df93f092501520bb36206703dadb65b25a3fbd0323c690dc8e72f5ee4a770feffffffea6905abb313a2aa3f6c8a056294abe06774dbf75688b03b96b8a2132aaf0cbf010000006b483045022100e4ab9dd0a75bc76c6c2cf549fb37c5577bad7f58953a7103abe4a77a95b873c10220545aa0c2b2869d444fb99d237549d6ac270c711d60788a6463ef4fee63ebd8fc4121031adea1da6e87b0771ea8c2a4723127d8cc9328b0594d159570ebe97b1e021c9efeffffff8c9a7a668dad3766f953d9779861f9c007b0a06f6ea2afbf8ab30137f34300fa000000006a47304402207253f724d891f5e1e66ec0c8084ade910a52257a1257933c23bd1b4da862e33a0220363df96e31dffa0a599b56c5049519a4d8ed34e96dc1fefecfd2bc31fc6d79d9412103186a4fc8445b3b437587c71f00fc9da7a267c0a38915fcf567528e310a73c0bdfeffffff82445d5b10b84b5256ef028615465e2d139c45584884c06e68bc38930d826e72010000006a47304402204846adc41599336307a087d4fa779a059ffe12c69456c82fa4b03942c901284002203e5f0c5e72b9ded7f48b4d22cbdb39390bea33003d46d8b4652c8ede1f13b3e54121031adea1da6e87b0771ea8c2a4723127d8cc9328b0594d159570ebe97b1e021c9efeffffffb8816c2c3b95aa8126f6d2d04798632b3167e6e2144d5f4e84cfb29e9d6f442d010000006a473044022078b1aff9a4ed3452f782db38341d846edd295f9a907c7373519408fb33eeb3240220578da5e91ec0c82604982b09cbd1f44e28260fcd640bcc55f086ce296ef32ef7412103c9bd0064d2759628c1f6e5ad9d6345a5bce64dc4f4bb0675162f77acd557e4e2feffffff70628ac9b2814f99fe4cd5f67a76047af533774ae90331fa8cb68e4dcbff1cb0010000006b483045022100cd88592589ab3bbd6e23920770a067a37ffbff3a31238167731377f11903676202202cb1c019365870dad3113abb3b0bc68ab9e65d9d60592f3315ffa444dfd88be741210393bd44ad6ed9295bf408e01bcdbdf6e4e8fd4a573ad20f37e54ff6e9b1596028feffffff027f766c02000000001976a9149f96c6e6c3aabf438eef5c589c47fa4b4f96592a88ac1c3d0f00000000001976a914e2ffd7cf2fe9468512878196d1b48fee9e9d003288ac56ea1200", + "txid": "0e21dd654596cac9f579e21a549a533d1be7319470fcf8f920a35d64cf020d1f", + "blocktime":1528796166, + "time":1528796166, + "locktime": 1239638, + "vin": [ + { + "txid": "f4be368fde7853c75d48c5927345df8d898f572e5d541fdad431e994f91e9c34", + "vout": 1, + "sequence": 4294967294, + "scriptSig": { + "hex": "4730440220351f1566e3ef02e900942103c60cba5a768cd710d3d1afbc75406099ad2d9e4702206e0f639a9991c7afb2136fb2e437629103ad0989898d1c90078ded5f08f5cb3341210303ae341929bdb242226a9a8c15cdbed5b89fa286842714d8be7e3f16c63abe11" + } + }, + { + "txid": "b46f64a97806dcf25c5f8cf8bcdba65fbfd705b7f1805be790f0c7efc885e64a", + "vout": 0, + "sequence": 4294967294, + "scriptSig": { + "hex": "483045022100b8dae1825b0d0ccbe212e8da6767ea049bad9acfc737e5c5ef3dc5eeef6d313c02207e4c669956f871a4a5f71903bf38a8c587b81940943682364b11fb1cd9c078d7412103c9bd0064d2759628c1f6e5ad9d6345a5bce64dc4f4bb0675162f77acd557e4e2" + } + }, + { + "txid": "1d2f4bb2a6320c7e4065f07545319af7826a03e2950d7dcb65713805ed1dc21a", + "vout": 1, + "sequence": 4294967294, + "scriptSig": { + "hex": "483045022100ef4a9469a5b3dbc0f03e8d8c5f254ad86f2c1e92e75a5ee737c3b3186b5edd95022076abcdfa976c3c78d2b196fb79699057248fad6d3d5e782524b85d84704394cc412103882df93f092501520bb36206703dadb65b25a3fbd0323c690dc8e72f5ee4a770" + } + }, + { + "txid": "bf0caf2a13a2b8963bb08856f7db7467e0ab9462058a6c3faaa213b3ab0569ea", + "vout": 1, + "sequence": 4294967294, + "scriptSig": { + "hex": "483045022100e4ab9dd0a75bc76c6c2cf549fb37c5577bad7f58953a7103abe4a77a95b873c10220545aa0c2b2869d444fb99d237549d6ac270c711d60788a6463ef4fee63ebd8fc4121031adea1da6e87b0771ea8c2a4723127d8cc9328b0594d159570ebe97b1e021c9e" + } + }, + { + "txid": "fa0043f33701b38abfafa26e6fa0b007c0f9619877d953f96637ad8d667a9a8c", + "vout": 0, + "sequence": 4294967294, + "scriptSig": { + "hex": "47304402207253f724d891f5e1e66ec0c8084ade910a52257a1257933c23bd1b4da862e33a0220363df96e31dffa0a599b56c5049519a4d8ed34e96dc1fefecfd2bc31fc6d79d9412103186a4fc8445b3b437587c71f00fc9da7a267c0a38915fcf567528e310a73c0bd" + } + }, + { + "txid": "726e820d9338bc686ec0844858459c132d5e46158602ef56524bb8105b5d4482", + "vout": 1, + "sequence": 4294967294, + "scriptSig": { + "hex": "47304402204846adc41599336307a087d4fa779a059ffe12c69456c82fa4b03942c901284002203e5f0c5e72b9ded7f48b4d22cbdb39390bea33003d46d8b4652c8ede1f13b3e54121031adea1da6e87b0771ea8c2a4723127d8cc9328b0594d159570ebe97b1e021c9e" + } + }, + { + "txid": "2d446f9d9eb2cf844e5f4d14e2e667312b639847d0d2f62681aa953b2c6c81b8", + "vout": 1, + "sequence": 4294967294, + "scriptSig": { + "hex": "473044022078b1aff9a4ed3452f782db38341d846edd295f9a907c7373519408fb33eeb3240220578da5e91ec0c82604982b09cbd1f44e28260fcd640bcc55f086ce296ef32ef7412103c9bd0064d2759628c1f6e5ad9d6345a5bce64dc4f4bb0675162f77acd557e4e2" + } + }, + { + "txid": "b01cffcb4d8eb68cfa3103e94a7733f57a04767af6d54cfe994f81b2c98a6270", + "vout": 1, + "sequence": 4294967294, + "scriptSig": { + "hex": "483045022100cd88592589ab3bbd6e23920770a067a37ffbff3a31238167731377f11903676202202cb1c019365870dad3113abb3b0bc68ab9e65d9d60592f3315ffa444dfd88be741210393bd44ad6ed9295bf408e01bcdbdf6e4e8fd4a573ad20f37e54ff6e9b1596028" + } + } + ], + "vout": [ + { + "value": 0.40662655, + "n": 0, + "scriptPubKey": { + "hex": "76a9149f96c6e6c3aabf438eef5c589c47fa4b4f96592a88ac" + } + }, + { + "value": 0.00998684, + "n": 1, + "scriptPubKey": { + "hex": "76a914e2ffd7cf2fe9468512878196d1b48fee9e9d003288ac" + } + } + ] + } + } +} diff --git a/bchain/types.go b/bchain/types.go index 538b9645..582e50b3 100644 --- a/bchain/types.go +++ b/bchain/types.go @@ -158,6 +158,7 @@ type BlockChainParser interface { GetAddrIDFromAddress(address string) ([]byte, error) // address to output script conversions AddressToOutputScript(address string) ([]byte, error) + OutputScriptToAddresses(script []byte) ([]string, error) // transactions PackedTxidLen() int PackTxid(txid string) ([]byte, error)