From cc311fc5fa162884ac51b39ecca432bc2f29c078 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20K=C3=BCchler?= Date: Thu, 1 Jul 2021 14:30:38 +0200 Subject: [PATCH 001/101] updated and added more testCases --- c/src/api/core/testCases.yml | 27 ++++++++++++++ c/src/api/eth1/testCases.yml | 12 +++++-- c/src/signer/pk-signer/testCases.yml | 14 ++++++++ c/src/verifier/eth1/basic/testCases.yml | 18 +++++----- c/src/verifier/eth1/nano/testCases.yml | 48 ++++++++++++------------- 5 files changed, 83 insertions(+), 36 deletions(-) create mode 100644 c/src/api/core/testCases.yml create mode 100644 c/src/signer/pk-signer/testCases.yml diff --git a/c/src/api/core/testCases.yml b/c/src/api/core/testCases.yml new file mode 100644 index 000000000..104d845be --- /dev/null +++ b/c/src/api/core/testCases.yml @@ -0,0 +1,27 @@ +utils: + + keccak: + input: + - "0x1234567890" + expected_output: + value: "0x3a56b02b60d4990074262f496ac34733f870e1b7815719b46ce155beac5e1a41" + type: "uint8Array" + + web3_sha3: + input: + - "0x1234567890" + expected_output: "0x3a56b02b60d4990074262f496ac34733f870e1b7815719b46ce155beac5e1a41" + + sha256: + input: + - "hello world" + expected_output: + value: "0xb94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9" + type: "uint8Array" + +account: + + in3_createKey: + input: + - "0x0fd65f7da55d811634495754f27ab318a3309e8b4b8a978a50c20a661117435a" + expected_output: "0x60a4bceeb5064f638f2e7e540e2ec7a0456aa9b2661afee41fb111800c95ec28" diff --git a/c/src/api/eth1/testCases.yml b/c/src/api/eth1/testCases.yml index 4147eb77d..e7f37e6be 100644 --- a/c/src/api/eth1/testCases.yml +++ b/c/src/api/eth1/testCases.yml @@ -30,7 +30,13 @@ utils: - eth - 3 expected_output: "0.158" - + + in3_toWei: + input: + - "20.0009123" + - eth + expected_output: "0x01159183c4793db800" + in3_calcDeployAddress: input: - "0x5a0b54d5dc17e0aadc383d2db43b0a0d3e029c4c" @@ -143,4 +149,6 @@ account: value: "15023483000000000" gasPrice: 1000000000 nonce: 32 - expected_output: "0xf86a20843b9aca00825208942c055df8d095a98099dc8942510a65d51480840e87355fc737810e00802da0fd2f892a7d154aa699ead599152d93674765eef4e6c384ffbc50db394ec3e3cea055ce9aee6e61256f7efaa9c714e4c342e21074d900f1d8399be720c56cc5f415" \ No newline at end of file + expected_output: "0xf86a20843b9aca00825208942c055df8d095a98099dc8942510a65d51480840e87355fc737810e00802da0fd2f892a7d154aa699ead599152d93674765eef4e6c384ffbc50db394ec3e3cea055ce9aee6e61256f7efaa9c714e4c342e21074d900f1d8399be720c56cc5f415" + + diff --git a/c/src/signer/pk-signer/testCases.yml b/c/src/signer/pk-signer/testCases.yml new file mode 100644 index 000000000..572d1e266 --- /dev/null +++ b/c/src/signer/pk-signer/testCases.yml @@ -0,0 +1,14 @@ +account: + + in3_addRawKey: + input: + - "0x1234567890123456789012345678901234567890123456789012345678901234" + expected_output: "0x2e988a386a799f506693793c6a5af6b54dfaabfb" + + eth_accounts: + - + expected_output: [] + - config: + pk: "0x4d5db4107d237df6a3d58ee5f70ae63d73d7658d4026f2eefd2f204c81682cb7" + expected_output: + - "0x00a329c0648769a73afac7f9381e08fb43dbea72" \ No newline at end of file diff --git a/c/src/verifier/eth1/basic/testCases.yml b/c/src/verifier/eth1/basic/testCases.yml index 555766947..05ba91815 100644 --- a/c/src/verifier/eth1/basic/testCases.yml +++ b/c/src/verifier/eth1/basic/testCases.yml @@ -187,17 +187,17 @@ eth: - "0xbf920c" expected_output: options: - blockdata: *result_blockfull - blockdataWithTxHashes: *result_blockfull_without_tx + eth_blockdata: *result_blockfull + eth_blockdataWithTxHashes: *result_blockfull_without_tx mockedResponses: options: - blockdata: + eth_blockdata: - eth_getBlockByNumber: - res: - jsonrpc: "2.0" result: *blockdata - blockdataWithTxHashes: + eth_blockdataWithTxHashes: - eth_getBlockByNumber: - res: - @@ -211,22 +211,22 @@ eth: - "0x250e327cbffe74b4de28ee3f7ebb77b0c2a8a712b93a9cd7413d6ac7ca3264c6" expected_output: options: - blockdata: *result_blockfull - blockdataWithTxHashes: *result_blockfull_without_tx + eth_blockdata: *result_blockfull + eth_blockdataWithTxHashes: *result_blockfull_without_tx mockedResponses: options: - blockdata: + eth_blockdata: - eth_getBlockByHash: - res: - jsonrpc: "2.0" result: *blockdata - blockdataWithTxHashes: + eth_blockdataWithTxHashes: - eth_getBlockByHash: - res: - jsonrpc: "2.0" - result: *blockdataWithTxHashes + result: *blockdataWithTxHashes eth_getBlockTransactionCountByHash: config: diff --git a/c/src/verifier/eth1/nano/testCases.yml b/c/src/verifier/eth1/nano/testCases.yml index 47fe90b7d..2c699e465 100644 --- a/c/src/verifier/eth1/nano/testCases.yml +++ b/c/src/verifier/eth1/nano/testCases.yml @@ -1,42 +1,40 @@ eth_tx_receipt: ð_tx_receipt - blockHash: '0x8220e66456e40636bff3a440832c9f179e4811d4e28269c7ab70142c3e5f9be2' - blockNumber: '0x8c2e8a' + blockHash: "0x8220e66456e40636bff3a440832c9f179e4811d4e28269c7ab70142c3e5f9be2" + blockNumber: "0x8c2e8a" contractAddress: null - cumulativeGasUsed: '0xa11af' - from: '0x3a9e354dee60df25c0389badafec8457e36ebfd2' - gasUsed: '0xa4b1' + cumulativeGasUsed: "0xa11af" + from: "0x3a9e354dee60df25c0389badafec8457e36ebfd2" + gasUsed: "0xa4b1" logs: - - address: '0x5b8174e20996ec743f01d3b55a35dd376429c596' - blockHash: '0x8220e66456e40636bff3a440832c9f179e4811d4e28269c7ab70142c3e5f9be2' - blockNumber: '0x8c2e8a' - data: '0x000000000000000000000000000000000000000000000029097c413dfab40000' - logIndex: '0x1' + - address: "0x5b8174e20996ec743f01d3b55a35dd376429c596" + blockHash: "0x8220e66456e40636bff3a440832c9f179e4811d4e28269c7ab70142c3e5f9be2" + blockNumber: "0x8c2e8a" + data: "0x000000000000000000000000000000000000000000000029097c413dfab40000" + logIndex: "0x1" removed: false topics: - - '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef' - - '0x0000000000000000000000003a9e354dee60df25c0389badafec8457e36ebfd2' - - '0x000000000000000000000000544d972d551061fc8e15e600f24f19021b8dfcfd' - transactionHash: '0x6188bf0672c005e30ad7c2542f2f048521662e30c91539d976408adf379bdae2' - transactionIndex: '0x1d' - transactionLogIndex: '0x0' + - "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef" + - "0x0000000000000000000000003a9e354dee60df25c0389badafec8457e36ebfd2" + - "0x000000000000000000000000544d972d551061fc8e15e600f24f19021b8dfcfd" + transactionHash: "0x6188bf0672c005e30ad7c2542f2f048521662e30c91539d976408adf379bdae2" + transactionIndex: "0x1d" + transactionLogIndex: "0x0" type: mined logsBloom: >- 0x00000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000010000000010004000000000000000000000000000000000000000000000000002000000000000000000000100000000000000000000000000000000000000000000000000000001002000000080000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000 - status: '0x1' - to: '0x5b8174e20996ec743f01d3b55a35dd376429c596' - transactionHash: '0x6188bf0672c005e30ad7c2542f2f048521662e30c91539d976408adf379bdae2' - transactionIndex: '0x1d' + status: "0x1" + to: "0x5b8174e20996ec743f01d3b55a35dd376429c596" + transactionHash: "0x6188bf0672c005e30ad7c2542f2f048521662e30c91539d976408adf379bdae2" + transactionIndex: "0x1d" eth: - eth_getTransactionReceipt: config: - proof: 'none' + proof: "none" input: - "0x6188bf0672c005e30ad7c2542f2f048521662e30c91539d976408adf379bdae2" expected_output: *eth_tx_receipt mockedResponses: - eth_getTransactionReceipt: - - res: - - - result: *eth_tx_receipt \ No newline at end of file + - res: + - result: *eth_tx_receipt From a26a00e43da3e2f2d7cb19332878bac3b3494355 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20K=C3=BCchler?= Date: Wed, 7 Jul 2021 17:12:34 +0200 Subject: [PATCH 002/101] added requests to testCases --- c/src/api/eth1/testCases.yml | 14 +- c/src/pay/zksync/testCases.yml | 405 +++++++++++++++++++----- c/src/verifier/btc/testCases.yml | 76 ++++- c/src/verifier/eth1/basic/testCases.yml | 173 ++++++++-- c/src/verifier/eth1/full/testCases.yml | 20 +- c/src/verifier/eth1/nano/testCases.yml | 9 +- c/src/verifier/ipfs/testCases.yml | 16 +- 7 files changed, 590 insertions(+), 123 deletions(-) diff --git a/c/src/api/eth1/testCases.yml b/c/src/api/eth1/testCases.yml index e7f37e6be..0fe700bea 100644 --- a/c/src/api/eth1/testCases.yml +++ b/c/src/api/eth1/testCases.yml @@ -74,11 +74,21 @@ account: expected_output: "0xe480808252089463f666a23cbd135a91187499b5cc51d589c302a085010000000080018080" mockedResponses: - eth_getTransactionCount: - - res: + req: + - + method: "eth_getTransactionCount" + params: + - "0xc2b2f4ad0d234b8c135c39eea8409b448e5e496f" + - "latest" + res: - result: "0x0" - eth_gasPrice: - - res: + req: + - + method: "eth_gasPrice" + params: [] + res: - result: "0x0" diff --git a/c/src/pay/zksync/testCases.yml b/c/src/pay/zksync/testCases.yml index 0248fab64..7b30a7f22 100644 --- a/c/src/pay/zksync/testCases.yml +++ b/c/src/pay/zksync/testCases.yml @@ -132,19 +132,29 @@ zksync: config: proof: 'none' experimental: true - # zksync: {} - # musig_urls: - # - "" - # - "https://approver.incubed.net" - #create_proof_method: "zk_wallet_create_signatures" - # verify_proof_method: 'zk_wallet_verify_proof' pk: "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" + rpc: "https://rinkeby-light.eth.linkpool.io" + zksync: + provider_url: "https://rinkeby-api.zksync.io/jsrpc" input: - "ETH" - expected_output: "sync:fa88b6eee5e695db8d1170ebba4c2bb2631f092a" + expected_output: "sync:ec0de4692863fc7b1459cb98c6be56ada438d991" mockedResponses: + - eth_chainId: + req: + - + method: "eth_chainId" + params: [] + res: + - + result: "0x4" - account_info: - - res: + req: + - + method: "account_info" + params: + - "0x8d33caff9b73a3eb24c83ac79bb5ed56126f284c" + res: - jsonrpc: '2.0' id: 1 @@ -168,11 +178,24 @@ zksync: address: '0x8d33caff9b73a3eb24c83ac79bb5ed56126f284c' - tokens: - - res: + req: + - + method: "tokens" + params: [] + res: - result: *tokens - get_tx_fee: - - res: + req: + - + method: "get_tx_fee" + params: + - + ChangePubKey: + onchainPubkeyAuth: false + - "0x8d33caff9b73a3eb24c83ac79bb5ed56126f284c" + - "ETH" + res: - result: zkpFee: 30541131762442 @@ -184,7 +207,31 @@ zksync: ChangePubKey: onchainPubkeyAuth: false - tx_submit: - - res: + req: + - + method: "tx_submit" + params: + - + nonce: 0 + fee: "64600000000000" + validUntil: 4294967295 + type: "ChangePubKey" + ethAuthData: + type: "ECDSA" + ethSignature: "0x2b281880b7c73127570aaa4696ea6024f826977649d15fc37e422ffc996121153a909302fad27e4548c66c7e0520b6f77c5027c88104b38fe82af16b85d4c7061b" + accountId: 167067 + signature: + pubKey: "1604e29d6544afa77334fce3964f68b01cdedbbdaf739355311195fd25292f04" + signature: "c936c89a624dc5effbb54bd3b2a2d56f4deac9103051d4607476770c3451d321784751218821e73f2f4d514068cd2bfd511bc4137fa28bdb660682944a754001" + validFrom: 0 + account: "0x8d33caff9b73a3eb24c83ac79bb5ed56126f284c" + feeToken: 0 + feeTokenId: 0 + newPkHash: "sync:ec0de4692863fc7b1459cb98c6be56ada438d991" + - null + - false + + res: - result: "sync-tx:4f8b59a5d7d4f128c3024b481eebc66de41428636c385ca68f00ea5f0d785564" @@ -193,6 +240,9 @@ zksync: proof: 'none' experimental: true pk: "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" + rpc: "https://rinkeby-light.eth.linkpool.io" + zksync: + provider_url: "https://rinkeby-api.zksync.io/jsrpc" input: - "0x448d2286d9d6996241ff1f87bd2e24692975cabd" - "100000000000000000" @@ -211,8 +261,21 @@ zksync: nonce: 3 txHash: "sync-tx:b431fad24a0b3ccc324c09b1dd3f2484ac070d944a615e46d7b822dd9e883c02" mockedResponses: + - eth_chainId: + req: + - + method: "eth_chainId" + params: [] + res: + - + result: "0x4" - account_info: - - res: + req: + - + method: "account_info" + params: + - "0x8d33caff9b73a3eb24c83ac79bb5ed56126f284c" + res: - result: depositing: @@ -234,14 +297,25 @@ zksync: pubKeyHash: 'sync:0000000000000000000000000000000000000000' address: '0x8d33caff9b73a3eb24c83ac79bb5ed56126f284c' - tokens: - - res: + req: + - + method: "tokens" + params: [] + res: - jsonrpc: '2.0' id: 3 result: *tokens - get_tx_fee: - - res: + req: + - + method: "get_tx_fee" + params: + - "Transfer" + - "0x448d2286d9d6996241ff1f87bd2e24692975cabd" + - "ETH" + res: - result: zkpFee: '27570375927574' @@ -251,15 +325,41 @@ zksync: gasPriceWei: '1000000000' feeType: TransferToNew - tx_submit: - - res: + req: + - + method: "tx_submit" + params: + - + amount: 100000000000000000 + nonce: 3 + from: "0x8d33caff9b73a3eb24c83ac79bb5ed56126f284c" + fee: 30300000000000 + validUntil: 4294967295 + validFrom: 0 + type: "Transfer" + accountId: 167067 + token: 0 + tokenId: 0 + signature: + pubKey: "1604e29d6544afa77334fce3964f68b01cdedbbdaf739355311195fd25292f04" + signature: "31cf12e7252010b008ac14d24d2c67a336d8dd46a5b224df40892029c8a2e41315b8345b39fde5384ab3875ec957512ae9be3fcee62eb01b82654d7ddb3cd603" + to: "0x448d2286d9d6996241ff1f87bd2e24692975cabd" + - + type: "EthereumSignature" + signature: "0x6937238185200aa4f7363c37b9ff885b90b56c1cc6b862c47733f4cc612fecb14cfdd34e42eddeab5c0d0247db8ca5588305a8b3571cab9218f50dbeef8003001b" + res: - result: "sync-tx:b431fad24a0b3ccc324c09b1dd3f2484ac070d944a615e46d7b822dd9e883c02" + zksync_deposit: config: proof: 'none' experimental: true pk: "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" + rpc: "https://rinkeby-light.eth.linkpool.io" + zksync: + provider_url: "https://rinkeby-api.zksync.io/jsrpc" input: - "10000000000000000" - "ETH" @@ -304,32 +404,68 @@ zksync: to: '0x82f67958a5474e40e1485742d648c0b0686b6e5d' priorityOpId: 63695 mockedResponses: + - eth_chainId: + req: + - + method: "eth_chainId" + params: [] + res: + - + result: "0x4" - contract_address: - - res: + req: + - + method: "contract_address" + params: [] + res: - result: mainContract: "0x82F67958A5474e40E1485742d648C0b0686b6e5D" govContract: "0xC8568F373484Cd51FDc1FE3675E46D8C0dc7D246" - tokens: - - res: + req: + - + method: "tokens" + params: [] + res: - jsonrpc: '2.0' id: 3 result: *tokens - eth_getTransactionCount: - - res: + req: + - + method: "eth_getTransactionCount" + params: + - "0x8d33caff9b73a3eb24c83ac79bb5ed56126f284c" + - "latest" + res: - result: "0x5" - eth_gasPrice: - - res: + req: + - + method: "eth_gasPrice" + params: [] + res: - result: "0x3b9aca00" - eth_sendRawTransaction: - - res: + req: + - + method: "eth_sendRawTransaction" + params: + - "0xf88f05843b9aca0083030d409482f67958a5474e40e1485742d648c0b0686b6e5d872386f26fc10000a42d2da8060000000000000000000000008d33caff9b73a3eb24c83ac79bb5ed56126f284c2ca0974482f63da156a0d76ef504e67a5ffb2c94d6d2d9182956746a6ea8df7f6934a007546b83049ce29a0fc38ba3aae98fa4c0ae32d0f86f0751b7ad534452024150" + res: - result: "0x19d13637be89661646a2cf2b62017ed08dc1b88e61144eda78a95207affc7f7e" - eth_getTransactionReceipt: - - res: + req: + - + method: "eth_getTransactionReceipt" + params: + - "0x19d13637be89661646a2cf2b62017ed08dc1b88e61144eda78a95207affc7f7e" + res: - jsonrpc: '2.0' id: 12 @@ -397,8 +533,21 @@ zksync: nonce: 2 txHash: "sync-tx:46e73c497fe623fbc9d41e0f8242f808cb80447b84e2bcba42fe5970f158aefa" mockedResponses: + - eth_chainId: + req: + - + method: "eth_chainId" + params: [] + res: + - + result: "0x4" - account_info: - - res: + req: + - + method: "account_info" + params: + - "0x8d33caff9b73a3eb24c83ac79bb5ed56126f284c" + res: - jsonrpc: '2.0' id: 2 @@ -421,13 +570,24 @@ zksync: depositing: balances: {} - tokens: - - res: + req: + - + method: "tokens" + params: [] + res: - jsonrpc: '2.0' id: 3 result: *tokens - get_tx_fee: - - res: + req: + - + method: "get_tx_fee" + params: + - "Withdraw" + - "0x8a91dc2d28b689474298d91899f0c1baf62cb85b" + - "ETH" + res: - jsonrpc: '2.0' id: 4 @@ -439,13 +599,31 @@ zksync: gasTxAmount: '53100' feeType: Withdraw - tx_submit: - - res: + req: - - result: "sync-tx:46e73c497fe623fbc9d41e0f8242f808cb80447b84e2bcba42fe5970f158aefa" - - eth_chainId: - - res: + method: "tx_submit" + params: + - + amount: 100 + nonce: 2 + from: "0x8d33caff9b73a3eb24c83ac79bb5ed56126f284c" + fee: 99500000000000 + type: "Withdraw" + validUntil: 4294967295 + accountId: 167067 + token: 0 + validFrom: 0 + signature: + pubKey: "1604e29d6544afa77334fce3964f68b01cdedbbdaf739355311195fd25292f04" + signature: "92626f9b38822a83e6e3ccb6d0b7926a47bd70170b3e6e31d8cb76ae22d1ca08bd705f2c2d5e2121ba48b49d3dd1a3c423f74194cd140e28708726da354dae01" + tokenId: 0 + to: "0x8a91dc2d28b689474298d91899f0c1baf62cb85b" + - + type: "EthereumSignature" + signature: "0x32a3417db2c73b2637da044834e6cff49f37bb73b7bd05d4256aaf240b17e48e09803948074e5bc7bd3d603e969872e42e7db89315a6f1c348f7f6e877b142911c" + res: - - result: "0x4" + result: "sync-tx:46e73c497fe623fbc9d41e0f8242f808cb80447b84e2bcba42fe5970f158aefa" zksync_emergency_withdraw: config: @@ -455,7 +633,6 @@ zksync: rpc: 'https://rinkeby-light.eth.linkpool.io' zksync: provider_url: 'https://rinkeby-light.eth.linkpool.io' - input: - ETH expected_output: @@ -476,19 +653,32 @@ zksync: mockedResponses: - contract_address: - - res: + req: + - + method: "contract_address" + params: [] + res: - result: govContract : "0xC8568F373484Cd51FDc1FE3675E46D8C0dc7D246" mainContract : "0x82F67958A5474e40E1485742d648C0b0686b6e5D" - tokens: - - res: + req: + - + method: "tokens" + params: [] + res: - jsonrpc: '2.0' id: 3 result: *tokens - account_info: - - res: + req: + - + method: "account_info" + params: + - "0x8d33caff9b73a3eb24c83ac79bb5ed56126f284c" + res: - jsonrpc: '2.0' id: 3 @@ -512,22 +702,42 @@ zksync: depositing: balances: {} - eth_getTransactionCount: - - res: + req: + - + method: "eth_getTransactionCount" + params: + - "0x8d33caff9b73a3eb24c83ac79bb5ed56126f284c" + - "latest" + res: - jsonrpc: "2.0" result: "0x6" - eth_gasPrice: - - res: + req: + - + method: "eth_gasPrice" + params: [] + res: - jsonrpc: "2.0" result: "0x3b9aca00" - eth_sendRawTransaction: - - res: + req: + - + method: "eth_sendRawTransaction" + params: + - "0xf8a906843b9aca008307a1209482f67958a5474e40e1485742d648c0b0686b6e5d80b844000000e20000000000000000000000000000000000000000000000000000000000028c9b00000000000000000000000000000000000000000000000000000000000000002ba06cc9a38b6d64bb73d50612a7fe8605cc591a4521e33f99daa98fea705cae059ea072824445db895c5d4aa81c1aaa6698f69bb9074c8ac9a4888f83b882e1744da2" + res: - jsonrpc: "2.0" result: "0x0557b4c73ebee5cd701c8ce86865385ee1aff57cf133ebd4d9b8ca8bd870a46c" - eth_getTransactionReceipt: - - res: + req: + - + method: "eth_getTransactionReceipt" + params: + - "0x0557b4c73ebee5cd701c8ce86865385ee1aff57cf133ebd4d9b8ca8bd870a46c" + res: - jsonrpc: '2.0' id: 13 @@ -546,10 +756,14 @@ zksync: 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 status: '0x0' to: '0x82f67958a5474e40e1485742d648c0b0686b6e5d' - - eth_chainId: - - res: - - - result: "0x4" + - eth_chainId: + req: + - + method: "eth_chainId" + params: [] + res: + - + result: "0x4" zksync_contract_address: config: @@ -561,7 +775,11 @@ zksync: govContract: "0xc8568f373484cd51fdc1fe3675e46d8c0dc7d246" mockedResponses: - contract_address: - - res: + req: + - + method: "contract_address" + params: [] + res: - result: govContract: "0xC8568F373484Cd51FDc1FE3675E46D8C0dc7D246" @@ -680,7 +898,11 @@ zksync: address: '0xd2084ea2ae4bbe1424e4fe3cde25b713632fb988' mockedResponses: - tokens: - - res: + req: + - + method: "tokens" + params: [] + res: - result: *tokens @@ -736,7 +958,12 @@ zksync: expected_output: 214.996782624198 mockedResponses: - get_token_price: - - res: + req: + - + method: "get_token_price" + params: + - "ETH" + res: - result: "214.9967826241980000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" @@ -758,7 +985,13 @@ zksync: feeType: 'Transfer' mockedResponses: - get_tx_fee: - - + req: + - + method: "get_tx_fee" + params: + - "Transfer" + - "0xabea9132b05a70803a4e85094fd0e1800777fbef" + - "BAT" res: - result: @@ -819,38 +1052,40 @@ zksync: block_number: 32027 to: "0x8c469877b27932abdd2313c4b6bf7cff5667fdb9" nonce: 8724 - mockedResponses: - - in3_http: + - in3_http: + req: - - res: - - - result: + method: "GET" + url: "https://rinkeby-api.zksync.io/api/v0.1/transactions_all/0x9b9f20c7c136a64f26bc3c63ef857e3c91e8ce307ae110f1dc1945bb41e629c1" + res: + - + result: + from: '0x3169131f0e744c1b8ef1ca8371c20d328f7f204d' + fail_reason: null + amount: '1' + tx_type: Transfer + created_at: '2021-06-10T13:16:55.148346' + tx: from: '0x3169131f0e744c1b8ef1ca8371c20d328f7f204d' - fail_reason: null amount: '1' - tx_type: Transfer - created_at: '2021-06-10T13:16:55.148346' - tx: - from: '0x3169131f0e744c1b8ef1ca8371c20d328f7f204d' - amount: '1' - accountId: 7873 - nonce: 8724 - signature: - signature: >- - 93f872d67e8746770e6cabd6777395d03c546fadf19dd5731fecd6795924f31059d425ee597c8c6eaf2653cb548ac5eee0404141bd428eb5819c0893ee777c02 - pubKey: cbe5d99bb60441dbc8f457372e305608a513a343dd564b2c11c5c0733f779fa9 - validFrom: 0 - fee: '0' - type: Transfer - to: '0x8c469877b27932abdd2313c4b6bf7cff5667fdb9' - token: 0 - validUntil: 184467440737095 + accountId: 7873 + nonce: 8724 + signature: + signature: >- + 93f872d67e8746770e6cabd6777395d03c546fadf19dd5731fecd6795924f31059d425ee597c8c6eaf2653cb548ac5eee0404141bd428eb5819c0893ee777c02 + pubKey: cbe5d99bb60441dbc8f457372e305608a513a343dd564b2c11c5c0733f779fa9 + validFrom: 0 fee: '0' - token: 0 - block_number: 32027 + type: Transfer to: '0x8c469877b27932abdd2313c4b6bf7cff5667fdb9' - nonce: 8724 + token: 0 + validUntil: 184467440737095 + fee: '0' + token: 0 + block_number: 32027 + to: '0x8c469877b27932abdd2313c4b6bf7cff5667fdb9' + nonce: 8724 zksync_account_history: config: @@ -858,7 +1093,7 @@ zksync: experimental: true pk: "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" zksync: - rest_api: "http://localhost:8080" + rest_api: "https://rinkeby-api.zksync.io/api/v0.1" input: - "0x3169131f0e744c1b8ef1ca8371c20d328f7f204d" expected_output: @@ -912,7 +1147,10 @@ zksync: tx_id: '32067,5' mockedResponses: - in3_http: - - + req: + - + method: "GET" + url: "https://rinkeby-api.zksync.io/api/v0.1/account/0x3169131f0e744c1b8ef1ca8371c20d328f7f204d/history/0/100" res: - result: @@ -991,7 +1229,12 @@ zksync: balances: {} mockedResponses: - account_info: - - res: + req: + - + method: "account_info" + params: + - "0x0e8b4fe889b126b9b502b244c9130912510f014f" + res: - result: address: '0x0e8b4fe889b126b9b502b244c9130912510f014f' @@ -1025,7 +1268,12 @@ zksync: success : null mockedResponses: - tx_info: - - res: + req: + - + method: "tx_info" + params: + - "sync-tx:e41d2489571d322189246dafa5ebde1f4699f498000000000000000000000000" + res: - result: executed : false @@ -1048,7 +1296,12 @@ zksync: executed : true mockedResponses: - ethop_info: - - res: + req: + - + method: ethop_info + params: + - 1 + res: - result: block: diff --git a/c/src/verifier/btc/testCases.yml b/c/src/verifier/btc/testCases.yml index 226851632..fd4240502 100644 --- a/c/src/verifier/btc/testCases.yml +++ b/c/src/verifier/btc/testCases.yml @@ -286,12 +286,24 @@ btc: options: bytes: - getblockheader: - - res: + req: + - + method: "getblockheader" + params: + - "00000000000000001e8d6829a8a21adc5d38d0a473b144b6765798e61f98bd1d" + - false + res: - result: 0100000081cd02ab7e569e8bcd9317e2fe99f2de44d49ab2b8851ba4a308000000000000e320b6c2fffc8d750423db8b1eb942ae710e951ed797f7affc8892b0f1fc122bc7f5d74df2b9441a42a14695 btcblockheader: - getblockheader: - - res: + req: + - + method: "getblockheader" + params: + - "00000000000000001e8d6829a8a21adc5d38d0a473b144b6765798e61f98bd1d" + - true + res: - result: hash: "00000000000000001e8d6829a8a21adc5d38d0a473b144b6765798e61f98bd1d" confirmations: 560364 @@ -323,17 +335,35 @@ btc: options: bytes: - getblock: - - res: + req: + - + method: getblock + params: + - "00000000000000001e8d6829a8a21adc5d38d0a473b144b6765798e61f98bd1d" + - 0 + res: - result: "0100000081cd02ab7e569e8bcd9317e2fe99f2de44d49ab2b8851ba4a308000000000000e320b6c2fffc8d750423db8b1eb942ae710e951ed797f7affc8892b0f1fc122bc7f5d74df2b9441a42a146950401000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0804f2b9441a022a01ffffffff014034152a01000000434104d879d5ef8b70cf0a33925101b64429ad7eb370da8ad0b05c9cd60922c363a1eada85bcc2843b7378e226735048786c790b30b28438d22acfade24ef047b5f865ac000000000100000001ad6279669bcc8e3003267d97c9e364a9835ea7a5b53871d057783ef96f468d73000000008c4930460221009805aa00cb6f80ca984584d4ca40f637fc948e3dbe159ea5c4eb6941bf4eb763022100e1cc0852d3f6eb87839edca1f90169088ed3502d8cde2f495840acac69eefc9801410486477e6a23cb25c9a99f0c467c6fc86197e718ebfd41d1aef7cc3cbd75197c1f1aaba985b22b366a0729ccb8aa38277809d6d218cf4077ac9f29a953b5435222ffffffff0280f0fa02000000001976a9146f31097e564b9d54ebad662d5c4b5621c18ff52388ac007ddaac000000001976a9147228033b48b380900501c39c61da4ab453ca88e888ac0000000001000000035a19f341c42071f9cec7df37c4853c95d6aecc95e3bf19e3181d30d99552b8c9000000008a473044022025bca5dc0fe42aca5f07c9b3fe1b3f72113ffbc3522f8d3ebb2457f5bdf8f9b2022030ff687c00a63e810b21e447d3a57b2749ebea553cab763eb9b99e1b9839653b014104469f7eb54b90d90106b1a5412b41a23516028e81ad35e0418a4460707ae39a4bf0101b632260fb08979aba0ceea576b5400c7cf30b539b055ec4c0b96ab00984ffffffff5b72d3f4b6b72b3511bddd9994f28a91cc03212f200f71b91df13e711d58c1da000000008c493046022100fbef2589b7c52a3be0fd8dd3624445da9c8930f0e51f6a33d76dc0ca0304473d0221009ec433ca6a9f16184db46468ff39cafaa9643021e0c66a1de1e6f9a612092790014104b27f4de096ac6431eec4b807a0d3db3e9f9be48faab692d5559624acb1faf4334dd440ebf32a81506b7c49d8cf40e4b3f5c6b6e99fcb6d3e8a298174bd2b348dffffffff292e94738851718433a3168e43cab1c6a811e9a0f35b06b6cec60fea9abe0f43010000008a4730440220582813f2c2d7cbb84521f81d6c2a1147e5296e90bee05f583b3df108fdac72010220232b43a2e596cef59f82c8bfff1a310d85e7beb3e607076ff8966d6d374dc12b014104a8514ca51137c6d8a4befa476a7521197b886fceafa9f5c2830bea6df62792a6dd46f2b26812b250f13fad473e5cab6dcceaa2d53cf2c82e8e03d95a0e70836bffffffff0240420f00000000001976a914429e6bd3c9a9ca4be00a4b2b02fd4f5895c1405988ac4083e81c000000001976a914e55756cb5395a4b39369d0f1f0a640c12fd867b288ac000000000100000002c8a8356402b9271ae73116b3a613d0a489aa3441a72d4b53a98eb7837584e17a010000008a4730440220771ae3ed7f2507f5682d6f63f59fa17187f1c4bdb33aa96373e73d42795d23b702206545376155d36db49560cf9c959d009f8e8ea668d93f47a4c8e9b27dc6b330230141048a976a8aa3f805749bf62df59168e49c163abafde1d2b596d685985807a221cbddf5fb72687678c41e35de46db82b49a48a2b9accea3648407c9ce2430724829ffffffffa4f0111c9248f7360b6e3fed4856563eb0aa82b10303c14befae96ed4818c7fe010000008c49304602210087fc57bd3ce0a03f0f7a3300a84dde8d5eba23dfdc64b8f2c17950c5213158d102210098141fbd22da33629cfc25b84d49b397144e1ec6287e0edd53dbb426aa6a72ed014104dee3ef362ae99b46422c8028f900a138c872776b2fcffed3f9cd02ee4b068a6df516a50249ae6d8f420f9ce19cdfc4663961296a71cd62b04a2c8a14ff89b1d0ffffffff01c0e1e400000000001976a914e43f7c61b3ef143b0fe4461c7d26f67377fd207588ac00000000" btcblock: - getblock: - - res: + req: + - + method: getblock + params: + - "00000000000000001e8d6829a8a21adc5d38d0a473b144b6765798e61f98bd1d" + - 1 + res: - result: *btc_full_with_tx_hash btcblockWithTx: - getblock: - - res: + req: + - + method: getblock + params: + - "00000000000000001e8d6829a8a21adc5d38d0a473b144b6765798e61f98bd1d" + - 2 + res: - result: *btc_full_with_tx @@ -350,12 +380,24 @@ btc: options: bytes: - getrawtransaction: - - res: + req: + - + method: "getrawtransaction" + params: + - "1427c7d1698e61afe061950226f1c149990b8c1e1b157320b0c4acf7d6b5605d" + - 0 + res: - result: "02000000000101adba296f842330296785f061ca9e152dec63fe235d0ef1d4d38cc4a67f586c7c0000000000feffffff0280f0fa020000000017a914e9f20f1225a9528739495649405861ae5d77ba1e871cc9df050000000017a9141abf9a43d3a56f06930b95b1a8f0161bc0b0c9be8702483045022100a1c74e429c4e40ef90d915556ce4b54a9aa4a83872622d0dbbaca3029f07f2d802204d99cd230b2e1d7378401d502cf589227272173f93b3ccc4aed6f97988067e780121035ad17694971c7dadab72369ab2444e355ae7d17ed8fba67aab80da9a3556d37c7cac0900" btctransaction: - getrawtransaction: - - res: + req: + - + method: "getrawtransaction" + params: + - "1427c7d1698e61afe061950226f1c149990b8c1e1b157320b0c4acf7d6b5605d" + - 1 + res: - result: *btc_full_tx @@ -365,7 +407,11 @@ btc: expected_output: 688582 mockedResponses: - getblockcount: - - res: + req: + - + method: "getblockcount" + params: [] + res: - result: 688582 @@ -375,7 +421,11 @@ btc: expected_output: 19932791027262.74 mockedResponses: - getdifficulty: - - res: + req: + - + method: "getdifficulty" + params: [] + res: - result: 19932791027262.74 @@ -385,6 +435,10 @@ btc: expected_output: "00000000000000000007337908f2581dc58cecd2d6e1aaaafe2260461e946096" mockedResponses: - getbestblockhash: - - res: + req: + - method: getbestblockhash + params: [] + res: - - result: "00000000000000000007337908f2581dc58cecd2d6e1aaaafe2260461e946096" \ No newline at end of file + result: "00000000000000000007337908f2581dc58cecd2d6e1aaaafe2260461e946096" + \ No newline at end of file diff --git a/c/src/verifier/eth1/basic/testCases.yml b/c/src/verifier/eth1/basic/testCases.yml index 05ba91815..1f1738afd 100644 --- a/c/src/verifier/eth1/basic/testCases.yml +++ b/c/src/verifier/eth1/basic/testCases.yml @@ -175,7 +175,11 @@ eth: expected_output: 3220 mockedResponses: - eth_blockNumber: - - res: + req: + - + method: "eth_blockNumber" + params: [] + res: - jsonrpc: "2.0" result: "0xc94" @@ -193,13 +197,25 @@ eth: options: eth_blockdata: - eth_getBlockByNumber: - - res: + req: + - + method: "eth_getBlockByNumber" + params: + - "0xbf920c" + - true + res: - jsonrpc: "2.0" result: *blockdata eth_blockdataWithTxHashes: - eth_getBlockByNumber: - - res: + req: + - + method: "eth_getBlockByNumber" + params: + - "0xbf920c" + - false + res: - jsonrpc: "2.0" result: *blockdataWithTxHashes @@ -217,13 +233,25 @@ eth: options: eth_blockdata: - eth_getBlockByHash: - - res: + req: + - + method: "eth_getBlockByHash" + params: + - "0x250e327cbffe74b4de28ee3f7ebb77b0c2a8a712b93a9cd7413d6ac7ca3264c6" + - true + res: - jsonrpc: "2.0" result: *blockdata eth_blockdataWithTxHashes: - eth_getBlockByHash: - - res: + req: + - + method: "eth_getBlockByHash" + params: + - "0x250e327cbffe74b4de28ee3f7ebb77b0c2a8a712b93a9cd7413d6ac7ca3264c6" + - false + res: - jsonrpc: "2.0" result: *blockdataWithTxHashes @@ -236,7 +264,12 @@ eth: expected_output: 204 mockedResponses: - eth_getBlockTransactionCountByHash: - - res: + req: + - + method: "eth_getBlockTransactionCountByHash" + params: + - "0x0c0728467cee3a0b1b1322e88596d0f9f2a8fa2018fc5447d5072805d3bf9d13" + res: - jsonrpc: "2.0" result: "0xcc" @@ -249,7 +282,12 @@ eth: expected_output: 204 mockedResponses: - eth_getBlockTransactionCountByNumber: - - res: + req: + - + method: "eth_getBlockTransactionCountByNumber" + params: + - "0x9d6a46" + res: - jsonrpc: "2.0" result: "0xcc" @@ -262,7 +300,12 @@ eth: expected_output: 1 mockedResponses: - eth_getUncleCountByBlockHash: - - res: + req: + - + method: "eth_getUncleCountByBlockHash" + params: + - "0x884aaab2f9116742e693ced034a2dff840b45f21709025f7d69cde26d071068b" + res: - jsonrpc: "2.0" result: "0x1" @@ -275,7 +318,12 @@ eth: expected_output: 1 mockedResponses: - eth_getUncleCountByBlockNumber: - - res: + req: + - + method: "eth_getUncleCountByBlockNumber" + params: + - "0x95ff5f" + res: - jsonrpc: "2.0" result: "0x1" @@ -289,7 +337,13 @@ eth: expected_output: *output_eth_getTransactionByBlock mockedResponses: - eth_getTransactionByBlockHashAndIndex: - - res: + req: + - + method: "eth_getTransactionByBlockHashAndIndex" + params: + - "0xca0e20a9e930af17c7422be3d991e925235b5350f8912a5ca4aaea734b4a88c5" + - "0x2" + res: - jsonrpc: "2.0" result: *rpc_eth_getTransactionByBlock @@ -303,7 +357,13 @@ eth: expected_output: *output_eth_getTransactionByBlock mockedResponses: - eth_getTransactionByBlockNumberAndIndex: - - res: + req: + - + method: "eth_getTransactionByBlockNumberAndIndex" + params: + - "0x9d6e99" + - "0x2" + res: - jsonrpc: "2.0" result: *rpc_eth_getTransactionByBlock @@ -316,7 +376,12 @@ eth: expected_output: *output_eth_getTransactionByBlock mockedResponses: - eth_getTransactionByHash: - - res: + req: + - + method: "eth_getTransactionByHash" + params: + - "0x02fb01822450cf847961e34edd4d30e8225bed8742a573fb3eb27205931b9637" + res: - jsonrpc: "2.0" result: *rpc_eth_getTransactionByBlock @@ -326,13 +391,21 @@ eth: proof: 'none' input: - - fromBlock: "0x834B77" - toBlock: "0x834B77" + fromBlock: "0x834b77" + toBlock: "0x834b77" address: "0xdac17f958d2ee523a2206206994597c13d831ec7" expected_output: *test_eth_getlogs mockedResponses: - eth_getLogs: - - res: + req: + - + method: "eth_getLogs" + params: + - + fromBlock: "0x834b77" + toBlock: "0x834b77" + address: "0xdac17f958d2ee523a2206206994597c13d831ec7" + res: - jsonrpc: "2.0" result: *test_eth_getlogs @@ -345,7 +418,13 @@ eth: expected_output: "0x329a1e26bab74000" mockedResponses: - eth_getBalance: - - res: + req: + - + method: "eth_getBalance" + params: + - "0x4144FFD5430a8518fa2d84ef5606Fd7e1921cE27" + - "latest" + res: - jsonrpc: "2.0" result: "0x329a1e26bab74000" @@ -358,7 +437,13 @@ eth: expected_output: 26588838 mockedResponses: - eth_getTransactionCount: - - res: + req: + - + method: "eth_getTransactionCount" + params: + - "0xea674fdde714fd979de3edf0f56aa9716b898ec8" + - "latest" + res: - jsonrpc: "2.0" result: "0x195b6a6" @@ -372,7 +457,13 @@ eth: expected_output: "0x60806040526001600160a01b036000541663530ca43760e11b6000351415602a578060005260206000f35b3660008037600080366000845af43d6000803e806046573d6000fd5b3d6000f3fea265627a7a723158203f36691c16ad212e606ff2acbeb8ed1efb9c7d0f4f2c44903f1d6dcb82754f6c64736f6c63430005110032" mockedResponses: - eth_getCode: - - res: + req: + - + method: "eth_getCode" + params: + - "0xf62A53c356f9DC6Ee521A74934236eD1e4D9F71a" + - "latest" + res: - jsonrpc: "2.0" result: "0x60806040526001600160a01b036000541663530ca43760e11b6000351415602a578060005260206000f35b3660008037600080366000845af43d6000803e806046573d6000fd5b3d6000f3fea265627a7a723158203f36691c16ad212e606ff2acbeb8ed1efb9c7d0f4f2c44903f1d6dcb82754f6c64736f6c63430005110032" @@ -386,7 +477,14 @@ eth: expected_output: "0x0" mockedResponses: - eth_getStorageAt: - - res: + req: + - + method: "eth_getStorageAt" + params: + - "0x862174623bc39e57de552538f424806b947d3d05" + - "0x0" + - "latest" + res: - jsonrpc: "2.0" result: "0x0" @@ -396,7 +494,6 @@ eth: proof: 'none' pk: "0x4d5db4107d237df6a3d58ee5f70ae63d73d7658d4026f2eefd2f204c81682cb7" chainId: 'goerli' - input: - to: "0x1234567890123456789012345678901234567890" @@ -404,13 +501,18 @@ eth: data: "0x4faa8a2600000000000000000000000000a329c0648769a73afac7f9381e08fb43dbea72" nonce: 31 gasPrice: 1000000000 - expected_output: "0xd5651b7c0b396c16ad9dc44ef0770aa215ca795702158395713facfbc9b55f38" + expected_output: "0x02de07114d5c6e5a81e73e164b4cb623727024822318b300b93bad54482a6416" mockedResponses: - eth_sendRawTransaction: - - res: + req: + - + method: "eth_sendRawTransaction" + params: + - "0xf8871f843b9aca0082520894123456789012345678901234567890123456789080a44faa8a2600000000000000000000000000a329c0648769a73afac7f9381e08fb43dbea722ea0d8642edc854eb204a4ab0e01cc7d91bbf70436df46d6b3c6103e49d13f0ecd97a05e3b81096a00b0703d18159cc4488b15d3d36b9dd7a125d2310ee152f6864375" + res: - jsonrpc: "2.0" - result: "0xd5651b7c0b396c16ad9dc44ef0770aa215ca795702158395713facfbc9b55f38" + result: "0x02de07114d5c6e5a81e73e164b4cb623727024822318b300b93bad54482a6416" eth_sendTransactionAndWait: config: @@ -469,12 +571,22 @@ eth: transactionIndex: "0x22" mockedResponses: - eth_sendRawTransaction: - - res: + req: + - + method: "eth_sendRawTransaction" + params: + - "0xf8871f843b9aca0082520894123456789012345678901234567890123456789080a44faa8a2600000000000000000000000000a329c0648769a73afac7f9381e08fb43dbea722ea0d8642edc854eb204a4ab0e01cc7d91bbf70436df46d6b3c6103e49d13f0ecd97a05e3b81096a00b0703d18159cc4488b15d3d36b9dd7a125d2310ee152f6864375" + res: - jsonrpc: "2.0" - result: "0xd5651b7c0b396c16ad9dc44ef0770aa215ca795702158395713facfbc9b55f38" + result: "0x02de07114d5c6e5a81e73e164b4cb623727024822318b300b93bad54482a6416" - eth_getTransactionReceipt: - - res: + req: + - + method: "eth_getTransactionReceipt" + params: + - "0x02de07114d5c6e5a81e73e164b4cb623727024822318b300b93bad54482a6416" + res: - jsonrpc: "2.0" result: @@ -531,7 +643,12 @@ eth: expected_output: "0x9c8024cc5a409df58f3949848f39c17d1e1d6e53bfe607adac77117fc2724fd2" mockedResponses: - eth_sendRawTransaction: - - res: - - + req: + - + method: "eth_sendRawTransaction" + params: + - "0xf86d8206aa85438558d400825208941ebd5c8cfec45650cf9c80adfeb5488ae36859c3872386f26fc10000801ba06df6fc901a78cea1dfc02baead56c8ec0d8d008c505efcfc3b4462b1a659be25a065152fd2e0dbf04b8e1baac46f31df9033f9c72b9dfad1b4fe41f89ef32c9a53" + res: + - jsonrpc: "2.0" result: "0x9c8024cc5a409df58f3949848f39c17d1e1d6e53bfe607adac77117fc2724fd2" \ No newline at end of file diff --git a/c/src/verifier/eth1/full/testCases.yml b/c/src/verifier/eth1/full/testCases.yml index 770f0fdb4..4662f3762 100644 --- a/c/src/verifier/eth1/full/testCases.yml +++ b/c/src/verifier/eth1/full/testCases.yml @@ -10,7 +10,15 @@ eth: expected_output: 2000000 mockedResponses: - eth_estimateGas: - - res: + req: + - + method: "eth_estimateGas" + params: + - + to: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2" + data: "0x18160ddd" + - "latest" + res: - result: "0x1E8480" @@ -24,6 +32,14 @@ eth: expected_output: "0x00000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000bc0ea09c1651a3d5d40bacb4356fb59159a99564000000000000000000000000000000000000000000000000000000000000ffff000000000000000000000000000000000000000000000000000000000000ffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002168747470733a2f2f696e332e736c6f636b2e69742f6d61696e6e65742f6e642d3400000000000000000000000000000000000000000000000000000000000000" mockedResponses: - eth_call: - - res: + req: + - + method: "eth_call" + params: + - + to: "0x2736D225f85740f42D17987100dc8d58e9e16252" + data: "0x5cf0f3570000000000000000000000000000000000000000000000000000000000000001" + - "latest" + res: - result: "0x00000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000bc0ea09c1651a3d5d40bacb4356fb59159a99564000000000000000000000000000000000000000000000000000000000000ffff000000000000000000000000000000000000000000000000000000000000ffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002168747470733a2f2f696e332e736c6f636b2e69742f6d61696e6e65742f6e642d3400000000000000000000000000000000000000000000000000000000000000" diff --git a/c/src/verifier/eth1/nano/testCases.yml b/c/src/verifier/eth1/nano/testCases.yml index 2c699e465..247ba4dad 100644 --- a/c/src/verifier/eth1/nano/testCases.yml +++ b/c/src/verifier/eth1/nano/testCases.yml @@ -36,5 +36,10 @@ eth: expected_output: *eth_tx_receipt mockedResponses: - eth_getTransactionReceipt: - - res: - - result: *eth_tx_receipt + req: + - + method: "eth_getTransactionReceipt" + params: + - "0x6188bf0672c005e30ad7c2542f2f048521662e30c91539d976408adf379bdae2" + res: + - result: *eth_tx_receipt diff --git a/c/src/verifier/ipfs/testCases.yml b/c/src/verifier/ipfs/testCases.yml index 96f85f1f0..1a1a68a27 100644 --- a/c/src/verifier/ipfs/testCases.yml +++ b/c/src/verifier/ipfs/testCases.yml @@ -9,7 +9,13 @@ ipfs: expected_output: "I love Incubed" mockedResponses: - ipfs_get: - - res: + req: + - + method: "ipfs_get" + params: + - Qmb5Z7B4mCCRSBTtqzF8cvejA9UqiZ3EoZFPVh21Vx2UoH + - utf8 + res: - result: "I love Incubed" @@ -22,6 +28,12 @@ ipfs: expected_output: "Qmb5Z7B4mCCRSBTtqzF8cvejA9UqiZ3EoZFPVh21Vx2UoH" mockedResponses: - ipfs_put: - - res: + req: + - + method: "ipfs_put" + params: + - "I love incubed" + - "utf8" + res: - result: "Qmb5Z7B4mCCRSBTtqzF8cvejA9UqiZ3EoZFPVh21Vx2UoH" \ No newline at end of file From d864ef981fb2934a4cbb132e63b567e0b8134265 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20K=C3=BCchler?= Date: Thu, 8 Jul 2021 11:42:49 +0200 Subject: [PATCH 003/101] updated btc with segwit block --- c/src/verifier/btc/rpc.yml | 2 + c/src/verifier/btc/testCases.yml | 2132 +++++++++++++++++++++++++++++- 2 files changed, 2089 insertions(+), 45 deletions(-) diff --git a/c/src/verifier/btc/rpc.yml b/c/src/verifier/btc/rpc.yml index 4e87e1ec9..1c0029e7c 100644 --- a/c/src/verifier/btc/rpc.yml +++ b/c/src/verifier/btc/rpc.yml @@ -131,6 +131,7 @@ types: reqSigs: descr: the required signatures type: int + optional: true type: descr: The type, eg 'pubkeyhash' type: string @@ -138,6 +139,7 @@ types: descr: Array of address(each representing a bitcoin adress) array: true type: string + optional: true btctransaction: txid: diff --git a/c/src/verifier/btc/testCases.yml b/c/src/verifier/btc/testCases.yml index fd4240502..933b78be5 100644 --- a/c/src/verifier/btc/testCases.yml +++ b/c/src/verifier/btc/testCases.yml @@ -256,6 +256,2002 @@ btc_full_tx: &btc_full_tx time: 1591782412 blocktime: 1591782412 +btcBlock_segwit_txHashes: &btcBlock_segwit_txHashes + hash: 0000000000000000000a276fc7641724fe5ad132f598c96eff403958e76667e2 + confirmations: 37 + strippedsize: 8058 + size: 12408 + weight: 36582 + height: 690099 + version: 536870916 + versionHex: '20000004' + merkleroot: 71c2a459044009c4daf075a0eb3ef45b70956287ef574b78f7f15a56b9896d76 + tx: + - e7ba742d3938f2f315f29e7ebe46d1d246487d34b85d346e427c6f444b579ba6 + - c1c8fd6d767548909882f61b1193a7ab6fde6890ed1ce63a8598097cac7f8568 + - 7c89e6b13b27c9bd8d0e6c2c4794ab6c71a7e606f9516175d6650a0386305253 + - 06efbaf78d677e7732028b8249174b8360b9be7f963bdc67864aad67a1be76e4 + - 79a048b9c6997cf4583a94db67d96748a906e897f2630d1de6c0cca1916757d7 + - f0cb50045c25d0841dfa90b5acdfa55498ca11e8a70cb3299499505128f3d98b + - fc36b2e4b006dca311ef2dab64294121662c834f3fb94410797355db82d512bc + - 934901b641164db57241fc59336b82ad6b67fc014d73140650620c87b0e0b20b + - af6ac62caaddcb34abd8c347d118b2a34695a6f28f593632c1bb6776937053e3 + - 826bf9e346ae54290d238c12226c130bcf813fe533e858fc1e083b9f983db6e9 + - 1b66512cd7c982b495fee0bd46662a8ce285f782961c8cac951c0717f64f93c8 + - 217e4dce0fab15ab73dd2e36f9b83ec5d68795788af5491672613b704e2c0578 + - 58bce502ea68bcd555d9e436404e82113dfc887f6d0af11f973e38d619c34389 + - f7a194e852d405fb98b665345bf9ec0ab0a5c4ac7ee3a44e9423494881e40ee9 + - a68dbd1477862e3bebbfde019aeda36a513cadd06f046f266a1d1b5ba0b9bbff + - ce91e574fec8d49959ec2b6772fbc57b39e863ca1f7533775cb428d68b686fef + - 322a50eb82656e81082572155771948a1903a808b2dfe51688af3ee85519a8f8 + - 4aaf9baf14a22f6a506d5b3ed98206c526e1f34f96ff33eab4ed5ac47c0c6d99 + - 29d96711529952ec9f46760537e0a778dc7dec4bfa84f869f2b30f62afd6b84f + - f9eb4c381c8dfe47095cf40f846f608fa20923f6b9e50e8db3448ffc6272854d + - c644b9829782ed1dbdc1e6b298f34e308a643b8c78009457d8c6f5ae5985a304 + - d12f4c3c074767aafc1d2240b3424efe45e8b38f5841cee92c17549c91b87c4c + - e4fdefc4634dc473e8098632ac800b34f600b25579eaee4a31d05389ee7411b1 + - 8d925bf3dff92af5db39bb866a75c610eddb9d7f290c4f8c7a71b449ae1cdaa9 + - c16f08cf1d0e53910ab1e297bf0d6b94141931f0cbf5e60f0f1fc55a09d6700b + - 2f8a80a59a5336fd31d9aa789b553fa4874a1cfff9216870048f4b000be9014f + - edd1110933f0c45d65fd67daf816b5ccb69eee41cc4e6cd3a2132815bc762ac5 + - 6bcc04db47b81fd8c2c317a5ddd4236afbe0e2c9f96065f333976202c46163c4 + - 53d90a6c9c6368dee7e1a3280c10db924ef3f92648465fdd0c40614f88e8c2c8 + - 4d944e129c6356d69a59196a845b7bcbbeb7898aae9a9acd817293ae982ad381 + - 62a7743d513269900956a793db563fa0b7e474924a0aefbf084af52dd319045d + - b0ac29dcca602bd28024c918942ba332e506ed132c6a7a41417d9b7f480731fb + time: 1625711473 + mediantime: 1625709499 + nonce: 3766546692 + bits: 171398ce + difficulty: 14363025673659.96 + chainwork: 00000000000000000000000000000000000000001f524d61662558d4d5cc1f48 + nTx: 32 + previousblockhash: 000000000000000000051d08578c5869136ba1fedc857c79c244846d3f988cf1 + nextblockhash: 00000000000000000013825a2e7d5da4f3f003ed6a7c05e0bcff3328a0366927 + +btc_full_segwit_block: &btc_full_segwit_block + hash: 0000000000000000000a276fc7641724fe5ad132f598c96eff403958e76667e2 + confirmations: 38 + strippedsize: 8058 + size: 12408 + weight: 36582 + height: 690099 + version: 536870916 + versionHex: '20000004' + merkleroot: 71c2a459044009c4daf075a0eb3ef45b70956287ef574b78f7f15a56b9896d76 + tx: + - txid: e7ba742d3938f2f315f29e7ebe46d1d246487d34b85d346e427c6f444b579ba6 + hash: 30ec34c04009fcc332257eeb60c514c3727674985325e8df06b8550e90f812a1 + version: 1 + size: 364 + vsize: 337 + weight: 1348 + locktime: 0 + vin: + - coinbase: >- + 03b3870a1e2f5669614254432f4d696e656420627920657266616e6d6f73616465712f2cfabe6d6d0fd649a10013c36addb756cf1d9c9218e8df928061dc99646b05a9f16c44301c1000000000000000106d391e0cabf695c5562fa47f7b150000 + sequence: 4294967295 + vout: + - value: 6.2523162 + 'n': 0 + scriptPubKey: + asm: >- + OP_DUP OP_HASH160 536ffa992491508dca0354e52f32a3a7a679a53a + OP_EQUALVERIFY OP_CHECKSIG + hex: 76a914536ffa992491508dca0354e52f32a3a7a679a53a88ac + reqSigs: 1 + type: pubkeyhash + addresses: + - 18cBEMRxXHqzWWCxZNtU91F5sbUNKhL5PX + - value: 0 + 'n': 1 + scriptPubKey: + asm: >- + OP_RETURN + 52534b424c4f434b3a0e83dfab6533b32ac33dbaabffc4b3f5d6ced40c50dcf46ee0031d2a003560dc + hex: >- + 6a2952534b424c4f434b3a0e83dfab6533b32ac33dbaabffc4b3f5d6ced40c50dcf46ee0031d2a003560dc + type: nulldata + - value: 0 + 'n': 2 + scriptPubKey: + asm: >- + OP_RETURN + b9e11b6dbffd356eb5da59e244a03b4144279f8dd61b4bb9813d812c4a9f9a20d9911391 + hex: >- + 6a24b9e11b6dbffd356eb5da59e244a03b4144279f8dd61b4bb9813d812c4a9f9a20d9911391 + type: nulldata + - value: 0 + 'n': 3 + scriptPubKey: + asm: >- + OP_RETURN + aa21a9ed2a45c4ead8566147106555d74ee978c78db04d97e716c3b1eac678fb63c78261 + hex: >- + 6a24aa21a9ed2a45c4ead8566147106555d74ee978c78db04d97e716c3b1eac678fb63c78261 + type: nulldata + hex: >- + 010000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff6103b3870a1e2f5669614254432f4d696e656420627920657266616e6d6f73616465712f2cfabe6d6d0fd649a10013c36addb756cf1d9c9218e8df928061dc99646b05a9f16c44301c1000000000000000106d391e0cabf695c5562fa47f7b150000ffffffff0404474425000000001976a914536ffa992491508dca0354e52f32a3a7a679a53a88ac00000000000000002b6a2952534b424c4f434b3a0e83dfab6533b32ac33dbaabffc4b3f5d6ced40c50dcf46ee0031d2a003560dc0000000000000000266a24b9e11b6dbffd356eb5da59e244a03b4144279f8dd61b4bb9813d812c4a9f9a20d99113910000000000000000266a24aa21a9ed2a45c4ead8566147106555d74ee978c78db04d97e716c3b1eac678fb63c782610120000000000000000000000000000000000000000000000000000000000000000000000000 + - txid: c1c8fd6d767548909882f61b1193a7ab6fde6890ed1ce63a8598097cac7f8568 + hash: 79be0873eab8a288a51b80f56372bf776e9c2915f8197aec7f8c3bf745305cfc + version: 1 + size: 214 + vsize: 133 + weight: 529 + locktime: 0 + vin: + - txid: ef780697c66bf523d478edda510a95269a7bfc266c3aba3faff3389d1fdfa2ed + vout: 39 + scriptSig: + asm: 0014764273e0504b0f3660c45e8ad0fa1ccc33c65186 + hex: 160014764273e0504b0f3660c45e8ad0fa1ccc33c65186 + txinwitness: + - >- + 304402205c03d3214220d20dd8a79849d67d69c778870e693af41c706755156944e2b8db022013a88f61457768e76060fd6e7a80cee5b53106099a53dc5723d54e6573a13c8601 + - 0327ad7578e80043bb5b2d51daa7012f433d7c3f34a81b4a506d40b32b24c267a8 + sequence: 4294967295 + vout: + - value: 0.51972292 + 'n': 0 + scriptPubKey: + asm: 0 508951bdcbdd0d956514e5544cd35b578b11ae41 + hex: 0014508951bdcbdd0d956514e5544cd35b578b11ae41 + reqSigs: 1 + type: witness_v0_keyhash + addresses: + - bc1q2zy4r0wtm5xe2eg5u42ye56m2793rtjp7lrwmr + hex: >- + 01000000000101eda2df1f9d38f3af3fba3a6c26fc7b9a26950a51daed78d423f56bc6970678ef2700000017160014764273e0504b0f3660c45e8ad0fa1ccc33c65186ffffffff01c408190300000000160014508951bdcbdd0d956514e5544cd35b578b11ae410247304402205c03d3214220d20dd8a79849d67d69c778870e693af41c706755156944e2b8db022013a88f61457768e76060fd6e7a80cee5b53106099a53dc5723d54e6573a13c8601210327ad7578e80043bb5b2d51daa7012f433d7c3f34a81b4a506d40b32b24c267a800000000 + - txid: 7c89e6b13b27c9bd8d0e6c2c4794ab6c71a7e606f9516175d6650a0386305253 + hash: 7c89e6b13b27c9bd8d0e6c2c4794ab6c71a7e606f9516175d6650a0386305253 + version: 1 + size: 191 + vsize: 191 + weight: 764 + locktime: 0 + vin: + - txid: 51ae0ccb43f5f738ad5ec9bc1549a84a14d466f7bf796cd5c09b53becec9750a + vout: 73 + scriptSig: + asm: >- + 304402206ecc7ee06ed9e5198a69f28926161ee6bd8050aeaf3e7f221d45d9907bd3acbf02203cd7ec7eb88555cf73100522b4ede5c58b9f10f0ccab010c01307866e47d618b[ALL] + 033ec98c3f20406c8748febca81c0755b46bb128db0142a642f8f447ef4e79d680 + hex: >- + 47304402206ecc7ee06ed9e5198a69f28926161ee6bd8050aeaf3e7f221d45d9907bd3acbf02203cd7ec7eb88555cf73100522b4ede5c58b9f10f0ccab010c01307866e47d618b0121033ec98c3f20406c8748febca81c0755b46bb128db0142a642f8f447ef4e79d680 + sequence: 4294967295 + vout: + - value: 0.0047954 + 'n': 0 + scriptPubKey: + asm: >- + OP_DUP OP_HASH160 528dad2141cd58294c0d3d8dd8d322d319956854 + OP_EQUALVERIFY OP_CHECKSIG + hex: 76a914528dad2141cd58294c0d3d8dd8d322d31995685488ac + reqSigs: 1 + type: pubkeyhash + addresses: + - 18XW8a8YaxpLZ3D7tHdJwgzB9GvX5gLUQw + hex: >- + 01000000010a75c9cebe539bc0d56c79bff766d4144aa84915bcc95ead38f7f543cb0cae51490000006a47304402206ecc7ee06ed9e5198a69f28926161ee6bd8050aeaf3e7f221d45d9907bd3acbf02203cd7ec7eb88555cf73100522b4ede5c58b9f10f0ccab010c01307866e47d618b0121033ec98c3f20406c8748febca81c0755b46bb128db0142a642f8f447ef4e79d680ffffffff0134510700000000001976a914528dad2141cd58294c0d3d8dd8d322d31995685488ac00000000 + - txid: 06efbaf78d677e7732028b8249174b8360b9be7f963bdc67864aad67a1be76e4 + hash: 06efbaf78d677e7732028b8249174b8360b9be7f963bdc67864aad67a1be76e4 + version: 1 + size: 191 + vsize: 191 + weight: 764 + locktime: 0 + vin: + - txid: 7dc40d7136d6c08ee1f57910e42e670691b44002f8243c1faf4554778b99a6b8 + vout: 2675 + scriptSig: + asm: >- + 304402201b42dcbac53ae8cd40a6b7fc9a115278c68cbac9e5dc1cda7b75e66dfc848545022077f349bd2f6517d8b4a95f1640ee871d1f2c48085529da499eaadf52d9ae6198[ALL] + 0226fb8a4429f73e7094d8125f8c8f3d9742306edad6bca096f2e501ca8f438842 + hex: >- + 47304402201b42dcbac53ae8cd40a6b7fc9a115278c68cbac9e5dc1cda7b75e66dfc848545022077f349bd2f6517d8b4a95f1640ee871d1f2c48085529da499eaadf52d9ae619801210226fb8a4429f73e7094d8125f8c8f3d9742306edad6bca096f2e501ca8f438842 + sequence: 4294967295 + vout: + - value: 0.00534228 + 'n': 0 + scriptPubKey: + asm: >- + OP_DUP OP_HASH160 528dad2141cd58294c0d3d8dd8d322d319956854 + OP_EQUALVERIFY OP_CHECKSIG + hex: 76a914528dad2141cd58294c0d3d8dd8d322d31995685488ac + reqSigs: 1 + type: pubkeyhash + addresses: + - 18XW8a8YaxpLZ3D7tHdJwgzB9GvX5gLUQw + hex: >- + 0100000001b8a6998b775445af1f3c24f80240b49106672ee41079f5e18ec0d636710dc47d730a00006a47304402201b42dcbac53ae8cd40a6b7fc9a115278c68cbac9e5dc1cda7b75e66dfc848545022077f349bd2f6517d8b4a95f1640ee871d1f2c48085529da499eaadf52d9ae619801210226fb8a4429f73e7094d8125f8c8f3d9742306edad6bca096f2e501ca8f438842ffffffff01d4260800000000001976a914528dad2141cd58294c0d3d8dd8d322d31995685488ac00000000 + - txid: 79a048b9c6997cf4583a94db67d96748a906e897f2630d1de6c0cca1916757d7 + hash: 79a048b9c6997cf4583a94db67d96748a906e897f2630d1de6c0cca1916757d7 + version: 1 + size: 192 + vsize: 192 + weight: 768 + locktime: 0 + vin: + - txid: 7dc40d7136d6c08ee1f57910e42e670691b44002f8243c1faf4554778b99a6b8 + vout: 3393 + scriptSig: + asm: >- + 3045022100d0c573af05451873741984fa8bf72ae132265ee13916cdfad90654730bcbb69902203d8c9ae9d4735efd901a97d8792f560eacc7c049414d5cef8c9774500585e6bd[ALL] + 0346702a3a0d900fdc122c7e5514d80f4edb84a2ed5b1c33fa165cc92398806885 + hex: >- + 483045022100d0c573af05451873741984fa8bf72ae132265ee13916cdfad90654730bcbb69902203d8c9ae9d4735efd901a97d8792f560eacc7c049414d5cef8c9774500585e6bd01210346702a3a0d900fdc122c7e5514d80f4edb84a2ed5b1c33fa165cc92398806885 + sequence: 4294967295 + vout: + - value: 0.00499396 + 'n': 0 + scriptPubKey: + asm: >- + OP_DUP OP_HASH160 528dad2141cd58294c0d3d8dd8d322d319956854 + OP_EQUALVERIFY OP_CHECKSIG + hex: 76a914528dad2141cd58294c0d3d8dd8d322d31995685488ac + reqSigs: 1 + type: pubkeyhash + addresses: + - 18XW8a8YaxpLZ3D7tHdJwgzB9GvX5gLUQw + hex: >- + 0100000001b8a6998b775445af1f3c24f80240b49106672ee41079f5e18ec0d636710dc47d410d00006b483045022100d0c573af05451873741984fa8bf72ae132265ee13916cdfad90654730bcbb69902203d8c9ae9d4735efd901a97d8792f560eacc7c049414d5cef8c9774500585e6bd01210346702a3a0d900fdc122c7e5514d80f4edb84a2ed5b1c33fa165cc92398806885ffffffff01c49e0700000000001976a914528dad2141cd58294c0d3d8dd8d322d31995685488ac00000000 + - txid: f0cb50045c25d0841dfa90b5acdfa55498ca11e8a70cb3299499505128f3d98b + hash: 821c43f8a3fdcab0861302ae1219854d7d180d252ec4033d0029de8e638fe272 + version: 1 + size: 223 + vsize: 142 + weight: 565 + locktime: 0 + vin: + - txid: 6d9d3cdcfc3f48a9a9412027d81c8f25da034ec192fea370e89056e831d36435 + vout: 0 + scriptSig: + asm: '' + hex: '' + txinwitness: + - >- + 30440220360091e4ca5a9e4f25eff0a9139123859499b69c5f8f1f48380eefffff3f2af402206a420e59a0373d450a94320e893500898236d717805a140ab6b64be5988c5b1801 + - 02064b8200ae425f73ac9a591094e4827b1a83ad6c44e8c8c7ca231649c0d189d9 + sequence: 4294967295 + vout: + - value: 0.03366305 + 'n': 0 + scriptPubKey: + asm: 0 6bb7140ad4c793d14021f48e672c2d266b3270c3 + hex: 00146bb7140ad4c793d14021f48e672c2d266b3270c3 + reqSigs: 1 + type: witness_v0_keyhash + addresses: + - bc1qdwm3gzk5c7fazspp7j8xwtpdye4nyuxrt2e5a6 + - value: 0.00448296 + 'n': 1 + scriptPubKey: + asm: OP_HASH160 584e23c934e8342026c14070ea525b36b244d8a6 OP_EQUAL + hex: a914584e23c934e8342026c14070ea525b36b244d8a687 + reqSigs: 1 + type: scripthash + addresses: + - 39jvzfxhTMW6PmCGA5Q6KzJMUHPPHGMhhZ + hex: >- + 010000000001013564d331e85690e870a3fe92c14e03da258f1cd8272041a9a9483ffcdc3c9d6d0000000000ffffffff02a15d3300000000001600146bb7140ad4c793d14021f48e672c2d266b3270c328d706000000000017a914584e23c934e8342026c14070ea525b36b244d8a687024730440220360091e4ca5a9e4f25eff0a9139123859499b69c5f8f1f48380eefffff3f2af402206a420e59a0373d450a94320e893500898236d717805a140ab6b64be5988c5b18012102064b8200ae425f73ac9a591094e4827b1a83ad6c44e8c8c7ca231649c0d189d900000000 + - txid: fc36b2e4b006dca311ef2dab64294121662c834f3fb94410797355db82d512bc + hash: aef19b8e97ab165e45ef0af0ec1202b95a248f52fef146c8ae0196449428d23c + version: 2 + size: 255 + vsize: 174 + weight: 693 + locktime: 690097 + vin: + - txid: 33acd772b5dcfecb3d684d033439e2259fbed85d7a5e806cd2764a8138a314c5 + vout: 8 + scriptSig: + asm: '' + hex: '' + txinwitness: + - >- + 304402206e1c1909a3cfff3f7f2ac82ebcb90fcdb3d9b07c8ed95d0a10478664f7d160c60220689aebf63dfc81d234298ad3ad8265f349039bffe243f9ec103f0821accf022801 + - 02eea9ba79990ec589ce0c60d895ae5283f933e98b583872f0e3e90e795becb897 + sequence: 4294967294 + vout: + - value: 0.00113685 + 'n': 0 + scriptPubKey: + asm: OP_HASH160 3b956676f8748666c71424b301a9a1d4554e0849 OP_EQUAL + hex: a9143b956676f8748666c71424b301a9a1d4554e084987 + reqSigs: 1 + type: scripthash + addresses: + - 3784mNc2kkbsHJdy96wBLamQYufCBUZ44d + - value: 3.48494348 + 'n': 1 + scriptPubKey: + asm: 0 ff955c763d5c6d5092e121ee42e806490704ecfc + hex: 0014ff955c763d5c6d5092e121ee42e806490704ecfc + reqSigs: 1 + type: witness_v0_keyhash + addresses: + - bc1ql724ca3at3k4pyhpy8hy96qxfyrsfm8u7020y2 + - value: 0.002 + 'n': 2 + scriptPubKey: + asm: OP_HASH160 e441bf8eb1b00e1e99c07984aeb5d1b23b8c26cf OP_EQUAL + hex: a914e441bf8eb1b00e1e99c07984aeb5d1b23b8c26cf87 + reqSigs: 1 + type: scripthash + addresses: + - 3NVvkYuzVnhhmB91HPhdJfqcx1BNVqjJdv + hex: >- + 02000000000101c514a338814a76d26c805e7a5dd8be9f25e23934034d683dcbfedcb572d7ac330800000000feffffff0315bc01000000000017a9143b956676f8748666c71424b301a9a1d4554e0849870c9ac51400000000160014ff955c763d5c6d5092e121ee42e806490704ecfc400d03000000000017a914e441bf8eb1b00e1e99c07984aeb5d1b23b8c26cf870247304402206e1c1909a3cfff3f7f2ac82ebcb90fcdb3d9b07c8ed95d0a10478664f7d160c60220689aebf63dfc81d234298ad3ad8265f349039bffe243f9ec103f0821accf0228012102eea9ba79990ec589ce0c60d895ae5283f933e98b583872f0e3e90e795becb897b1870a00 + - txid: 934901b641164db57241fc59336b82ad6b67fc014d73140650620c87b0e0b20b + hash: b13f922b564a244e24892d19528563432ccd918456a67929ee4b9fcc52a70b3a + version: 2 + size: 223 + vsize: 142 + weight: 565 + locktime: 690097 + vin: + - txid: 6a9a93a5253e16c58c2383b2c0060f9ef0aa3bed3e43bbee54cd91a84109329d + vout: 0 + scriptSig: + asm: '' + hex: '' + txinwitness: + - >- + 30440220307ddd38d20a7214177077d497424f77284c7846477b8882f26c82f928f7e4a00220643c16e67e1397749732076c03355f9b0ef1e4ef27e3953c986f439cff94ebb301 + - 020a820f6114b3cdf4d761ca1f31aa2d9dd19ae4c7eea7e694709b9ac94a4455cc + sequence: 4294967293 + vout: + - value: 0.00113228 + 'n': 0 + scriptPubKey: + asm: 0 1debbd78f6e6734ba3ad902df3781d8010ade747 + hex: 00141debbd78f6e6734ba3ad902df3781d8010ade747 + reqSigs: 1 + type: witness_v0_keyhash + addresses: + - bc1qrh4m678kuee5hgadjqklx7qasqg2me68fvnlm3 + - value: 0.00449488 + 'n': 1 + scriptPubKey: + asm: OP_HASH160 7b9a9e6d60400e5deb08c2be1a72a4afd411337e OP_EQUAL + hex: a9147b9a9e6d60400e5deb08c2be1a72a4afd411337e87 + reqSigs: 1 + type: scripthash + addresses: + - 3CxaGFBiLsRGMrib6QtN4YTA4j8r9vBpyy + hex: >- + 020000000001019d320941a891cd54eebb433eed3baaf09e0f06c0b283238cc5163e25a5939a6a0000000000fdffffff024cba0100000000001600141debbd78f6e6734ba3ad902df3781d8010ade747d0db06000000000017a9147b9a9e6d60400e5deb08c2be1a72a4afd411337e87024730440220307ddd38d20a7214177077d497424f77284c7846477b8882f26c82f928f7e4a00220643c16e67e1397749732076c03355f9b0ef1e4ef27e3953c986f439cff94ebb30121020a820f6114b3cdf4d761ca1f31aa2d9dd19ae4c7eea7e694709b9ac94a4455ccb1870a00 + - txid: af6ac62caaddcb34abd8c347d118b2a34695a6f28f593632c1bb6776937053e3 + hash: 16fc818d5e8e83b7061c1deb08b8e359e670ba86cdc4ff95c9e177da0bb36da4 + version: 1 + size: 1799 + vsize: 1717 + weight: 6866 + locktime: 0 + vin: + - txid: 4d8ddbbe5f5c81597919285e4ff8be2d968c4a18d51f49539b51d0d7665f3c9e + vout: 59 + scriptSig: + asm: '' + hex: '' + txinwitness: + - >- + 304502210089ca3893f1180326d1bbc27f89b23ce5e2ef4f35c9130eaff088f0484896c08f02205559db4a068aaa1547972e18ce77181de04206e8d2e2a4b2bfcff6a531cce19901 + - 02efd56b2aa9c332bafdadee106a21d3feea0e93e83b2c01e30172719b5e5a0e0b + sequence: 4294967295 + vout: + - value: 0.0304203 + 'n': 0 + scriptPubKey: + asm: >- + OP_DUP OP_HASH160 c378ded906a60a72b6345b5eaff0d933427218a5 + OP_EQUALVERIFY OP_CHECKSIG + hex: 76a914c378ded906a60a72b6345b5eaff0d933427218a588ac + reqSigs: 1 + type: pubkeyhash + addresses: + - 1JpZZduyUs75KZoqQHyqy8NvW4Yj7eapNJ + - value: 0.01575548 + 'n': 1 + scriptPubKey: + asm: 0 cb60668f051c001353e14e4218806911879e934e + hex: 0014cb60668f051c001353e14e4218806911879e934e + reqSigs: 1 + type: witness_v0_keyhash + addresses: + - bc1qedsxdrc9rsqpx5lpfepp3qrfzxreay6waydz3k + - value: 0.00269812 + 'n': 2 + scriptPubKey: + asm: OP_HASH160 53e13860d18555d9d2d595c8df33823a177d40ee OP_EQUAL + hex: a91453e13860d18555d9d2d595c8df33823a177d40ee87 + reqSigs: 1 + type: scripthash + addresses: + - 39LXp3MZZjtVJ5CaH8H6tKP1rEgZZXtxE8 + - value: 0.01453799 + 'n': 3 + scriptPubKey: + asm: OP_HASH160 02de054ac7322088ff02f28d09f4e24653e870b7 OP_EQUAL + hex: a91402de054ac7322088ff02f28d09f4e24653e870b787 + reqSigs: 1 + type: scripthash + addresses: + - 31xBFCDRYaBFJBJcDRQDN2uA9odx4oCmhy + - value: 0.00335709 + 'n': 4 + scriptPubKey: + asm: >- + OP_DUP OP_HASH160 6b6c4f33d3931c52cc3760e0e864ac905b5aafb0 + OP_EQUALVERIFY OP_CHECKSIG + hex: 76a9146b6c4f33d3931c52cc3760e0e864ac905b5aafb088ac + reqSigs: 1 + type: pubkeyhash + addresses: + - 1Ao13zeE4dr12kChGSpVziCVQNMdssZZPg + - value: 0.001412 + 'n': 5 + scriptPubKey: + asm: OP_HASH160 03c04e312012941bbc2941e2a1c9e1db3f58e741 OP_EQUAL + hex: a91403c04e312012941bbc2941e2a1c9e1db3f58e74187 + reqSigs: 1 + type: scripthash + addresses: + - 322rKjbfXr3sHKWYc28NoSSxEAXDrh8JQr + - value: 0.00119916 + 'n': 6 + scriptPubKey: + asm: OP_HASH160 4eb5ef7073cfa46e1dcbd432e5461169b69d87d1 OP_EQUAL + hex: a9144eb5ef7073cfa46e1dcbd432e5461169b69d87d187 + reqSigs: 1 + type: scripthash + addresses: + - 38sCabNdWjpDF1vsXT3zMZu7wBwdTyxJ76 + - value: 0.00056951 + 'n': 7 + scriptPubKey: + asm: OP_HASH160 8b219ff8975fdc4e92e99f2adc52396cf86d23b0 OP_EQUAL + hex: a9148b219ff8975fdc4e92e99f2adc52396cf86d23b087 + reqSigs: 1 + type: scripthash + addresses: + - 3ENg8WKQ4YC2nZrssnGuLjrtrPhdzU7NFK + - value: 0.00020192 + 'n': 8 + scriptPubKey: + asm: >- + OP_DUP OP_HASH160 9a716a4e526dc3e1ff3d8fdb9513d21a584bb41f + OP_EQUALVERIFY OP_CHECKSIG + hex: 76a9149a716a4e526dc3e1ff3d8fdb9513d21a584bb41f88ac + reqSigs: 1 + type: pubkeyhash + addresses: + - 1F5cvmnTH3ncX6YEMAstU6ceP9Kw9Rmq9M + - value: 0.00419707 + 'n': 9 + scriptPubKey: + asm: >- + OP_DUP OP_HASH160 e739159436dcac622b027fc8fe03266a940ec821 + OP_EQUALVERIFY OP_CHECKSIG + hex: 76a914e739159436dcac622b027fc8fe03266a940ec82188ac + reqSigs: 1 + type: pubkeyhash + addresses: + - 1N5bUbk87zwDb6ALZ6UEyvNRKaRnN4NbNR + - value: 0.0007791 + 'n': 10 + scriptPubKey: + asm: OP_HASH160 5e683f3531dc04fbfd40f77375e920d5d241a954 OP_EQUAL + hex: a9145e683f3531dc04fbfd40f77375e920d5d241a95487 + reqSigs: 1 + type: scripthash + addresses: + - 3AJCKn4iq68W5qnYcvThruWuQY7r1z3k2H + - value: 0.00068243 + 'n': 11 + scriptPubKey: + asm: >- + OP_DUP OP_HASH160 7762c98e0e3367094084716de9c539d489e64417 + OP_EQUALVERIFY OP_CHECKSIG + hex: 76a9147762c98e0e3367094084716de9c539d489e6441788ac + reqSigs: 1 + type: pubkeyhash + addresses: + - 1BtFkh6uq7KSZcQwfqxkHdoZiSY1nZiEXi + - value: 0.00604712 + 'n': 12 + scriptPubKey: + asm: >- + OP_DUP OP_HASH160 08f99e916e4cf152e6a241c05c79cedc09084864 + OP_EQUALVERIFY OP_CHECKSIG + hex: 76a91408f99e916e4cf152e6a241c05c79cedc0908486488ac + reqSigs: 1 + type: pubkeyhash + addresses: + - 1pTSPv2KKcAbdFZTwme94vhdiJQtyfdY4 + - value: 0.00425588 + 'n': 13 + scriptPubKey: + asm: OP_HASH160 d3f1766bf4170e8491e522abc5f403c8c5b00cb3 OP_EQUAL + hex: a914d3f1766bf4170e8491e522abc5f403c8c5b00cb387 + reqSigs: 1 + type: scripthash + addresses: + - 3M1fm8keq5aD2h6RuQuKXv1P75Qs5BvYoa + - value: 0.00284066 + 'n': 14 + scriptPubKey: + asm: OP_HASH160 af3ed025d98feaf94600c016bc71023edc305273 OP_EQUAL + hex: a914af3ed025d98feaf94600c016bc71023edc30527387 + reqSigs: 1 + type: scripthash + addresses: + - 3HfdRSfEZkFnkLS6dN52w5VjE6uzoBHsa1 + - value: 0.00599581 + 'n': 15 + scriptPubKey: + asm: OP_HASH160 7fc5ada0ec0d456d5c5b58fd21b7968bdd7a02df OP_EQUAL + hex: a9147fc5ada0ec0d456d5c5b58fd21b7968bdd7a02df87 + reqSigs: 1 + type: scripthash + addresses: + - 3DLcYq9P6MN2HVPooeRcqXER9X4aBEBndn + - value: 0.06290286 + 'n': 16 + scriptPubKey: + asm: OP_HASH160 e0e95aacb6866119226c2b391fbb8e165e1b9c87 OP_EQUAL + hex: a914e0e95aacb6866119226c2b391fbb8e165e1b9c8787 + reqSigs: 1 + type: scripthash + addresses: + - 3NCEqFKTcDSiifRY57d4qFAwBFQRmNuijS + - value: 0.00053355 + 'n': 17 + scriptPubKey: + asm: >- + OP_DUP OP_HASH160 51564fb5db5530ec7d6fa333647a01af7380d217 + OP_EQUALVERIFY OP_CHECKSIG + hex: 76a91451564fb5db5530ec7d6fa333647a01af7380d21788ac + reqSigs: 1 + type: pubkeyhash + addresses: + - 18R58ZKjfXUTZiYGdkwFuB3uuXXXrKjVra + - value: 0.11230255 + 'n': 18 + scriptPubKey: + asm: OP_HASH160 9501fed908d5114cedd9386660873e62ca2f3dff OP_EQUAL + hex: a9149501fed908d5114cedd9386660873e62ca2f3dff87 + reqSigs: 1 + type: scripthash + addresses: + - 3FGtzmyPenpW1o6jNeL8X36R8hB6ZortH3 + - value: 0.00449093 + 'n': 19 + scriptPubKey: + asm: OP_HASH160 b83032f7d5cca0051f788f1a2eff90ab2d79e3d4 OP_EQUAL + hex: a914b83032f7d5cca0051f788f1a2eff90ab2d79e3d487 + reqSigs: 1 + type: scripthash + addresses: + - 3JUuzmkMPhGjKXzuDBmqJS2gyMmdwy8XfR + - value: 0.005768 + 'n': 20 + scriptPubKey: + asm: >- + OP_DUP OP_HASH160 eeb8bacc9220f59abb663e432985ee200d427f30 + OP_EQUALVERIFY OP_CHECKSIG + hex: 76a914eeb8bacc9220f59abb663e432985ee200d427f3088ac + reqSigs: 1 + type: pubkeyhash + addresses: + - 1NmF7u9aTbeq5AP2sbW3f1q6uosFuig7pK + - value: 0.00284898 + 'n': 21 + scriptPubKey: + asm: 0 4a12310c411a22a565621fa258e8426bd7c8d0b3 + hex: 00144a12310c411a22a565621fa258e8426bd7c8d0b3 + reqSigs: 1 + type: witness_v0_keyhash + addresses: + - bc1qfgfrzrzprg322etzr73936zzd0tu359nujnlfl + - value: 0.003 + 'n': 22 + scriptPubKey: + asm: OP_HASH160 d5d8c6caf78fc21061fc4731c24b0c89a36c7ad6 OP_EQUAL + hex: a914d5d8c6caf78fc21061fc4731c24b0c89a36c7ad687 + reqSigs: 1 + type: scripthash + addresses: + - 3MBjYJRqvTJWpUWJQXeRwtJjQzjscbp41M + - value: 0.00075 + 'n': 23 + scriptPubKey: + asm: OP_HASH160 8289e1a729717438ebcdf8c9e07596ec2d3acbaa OP_EQUAL + hex: a9148289e1a729717438ebcdf8c9e07596ec2d3acbaa87 + reqSigs: 1 + type: scripthash + addresses: + - 3DbEweqv1HzaBVYB4F8wNgmrzoQYkVbcec + - value: 0.00287073 + 'n': 24 + scriptPubKey: + asm: >- + OP_DUP OP_HASH160 6451b87e24ca86905eea9d851e28c5b8aa9dee39 + OP_EQUALVERIFY OP_CHECKSIG + hex: 76a9146451b87e24ca86905eea9d851e28c5b8aa9dee3988ac + reqSigs: 1 + type: pubkeyhash + addresses: + - 1A9SUEdmz4FKARPZgM2h26MoiNyhUdzPq2 + - value: 0.001681 + 'n': 25 + scriptPubKey: + asm: >- + OP_DUP OP_HASH160 d37556e83e286f550870db5c825e6fffc312e555 + OP_EQUALVERIFY OP_CHECKSIG + hex: 76a914d37556e83e286f550870db5c825e6fffc312e55588ac + reqSigs: 1 + type: pubkeyhash + addresses: + - 1LH69NFFXdbkCcRzbS18N71gX4nBwmSUpk + - value: 0.0001499 + 'n': 26 + scriptPubKey: + asm: 0 353b138c3be7387ddc491c83e7159d736c537de1 + hex: 0014353b138c3be7387ddc491c83e7159d736c537de1 + reqSigs: 1 + type: witness_v0_keyhash + addresses: + - bc1qx5a38rpmuuu8mhzfrjp7w9vawdk9xl0pv2lkw2 + - value: 0.00074948 + 'n': 27 + scriptPubKey: + asm: >- + OP_DUP OP_HASH160 845c12e6aedc4cdbc79f2eacce9ca30d631b9aa7 + OP_EQUALVERIFY OP_CHECKSIG + hex: 76a914845c12e6aedc4cdbc79f2eacce9ca30d631b9aa788ac + reqSigs: 1 + type: pubkeyhash + addresses: + - 1D4rViyML5HzizezD6MbaVeKAA5R9924EG + - value: 0.00081844 + 'n': 28 + scriptPubKey: + asm: >- + OP_DUP OP_HASH160 0e09830988a068eb6507dbae420639dd881b47c4 + OP_EQUALVERIFY OP_CHECKSIG + hex: 76a9140e09830988a068eb6507dbae420639dd881b47c488ac + reqSigs: 1 + type: pubkeyhash + addresses: + - 12HDrajJ7RB6aBzUY4DKRYjfMBPLbduobh + - value: 0.00168096 + 'n': 29 + scriptPubKey: + asm: >- + OP_DUP OP_HASH160 7e66edc27e301deb97e19ce70e4204ea670196e1 + OP_EQUALVERIFY OP_CHECKSIG + hex: 76a9147e66edc27e301deb97e19ce70e4204ea670196e188ac + reqSigs: 1 + type: pubkeyhash + addresses: + - 1CXMSnZP8h2byzS3HSj9qNjRTDFDBtCNsC + - value: 0.00079431 + 'n': 30 + scriptPubKey: + asm: OP_HASH160 168046f69a90adcf31e4ed4dd580b643894f3815 OP_EQUAL + hex: a914168046f69a90adcf31e4ed4dd580b643894f381587 + reqSigs: 1 + type: scripthash + addresses: + - 33jzTcvTv6vzaXte2WAbAwFFVEyZf9DMCP + - value: 0.02874012 + 'n': 31 + scriptPubKey: + asm: 0 23b91d13fd85c250078bef3e696141afbc7d67d7 + hex: 001423b91d13fd85c250078bef3e696141afbc7d67d7 + reqSigs: 1 + type: witness_v0_keyhash + addresses: + - bc1qywu36ylashp9qputaulxjc2p47786e7h49khmw + - value: 0.00023983 + 'n': 32 + scriptPubKey: + asm: >- + OP_DUP OP_HASH160 81316d20a965c57e365ddbd88cf0b33df182497c + OP_EQUALVERIFY OP_CHECKSIG + hex: 76a91481316d20a965c57e365ddbd88cf0b33df182497c88ac + reqSigs: 1 + type: pubkeyhash + addresses: + - 1Cn7NwmRDBdcnknkB5dTaG1tQZLGkH9VhV + - value: 0.00056266 + 'n': 33 + scriptPubKey: + asm: OP_HASH160 40aa6e55061da5ef2b270b375d169df7d578785a OP_EQUAL + hex: a91440aa6e55061da5ef2b270b375d169df7d578785a87 + reqSigs: 1 + type: scripthash + addresses: + - 37awLaCvyD61vHfk1TCTWh1aAJbZPQU2cY + - value: 0.002848 + 'n': 34 + scriptPubKey: + asm: OP_HASH160 71084b0c6799c2db9ad5ba2afd88af69cfaf38db OP_EQUAL + hex: a91471084b0c6799c2db9ad5ba2afd88af69cfaf38db87 + reqSigs: 1 + type: scripthash + addresses: + - 3BzgDSS6tiLzu3YLHuA1ZvfzVyZZ2uYrAS + - value: 0.05660079 + 'n': 35 + scriptPubKey: + asm: >- + OP_DUP OP_HASH160 fd61259381494884b2094a6c7e015ecf964dcedb + OP_EQUALVERIFY OP_CHECKSIG + hex: 76a914fd61259381494884b2094a6c7e015ecf964dcedb88ac + reqSigs: 1 + type: pubkeyhash + addresses: + - 1Q6kLQmiE4RP428d85VGYH7cANJ4XkEZ62 + - value: 0.002848 + 'n': 36 + scriptPubKey: + asm: >- + OP_DUP OP_HASH160 d3e27eac3b18ab2fe0e543b0e24a457aba4508a7 + OP_EQUALVERIFY OP_CHECKSIG + hex: 76a914d3e27eac3b18ab2fe0e543b0e24a457aba4508a788ac + reqSigs: 1 + type: pubkeyhash + addresses: + - 1LKLucVQYdE7HQK6Vayg5GM7JyNN3fWe3v + - value: 0.00014987 + 'n': 37 + scriptPubKey: + asm: 0 4bf26007bb626433beb32f46989c534c0ea36b94 + hex: 00144bf26007bb626433beb32f46989c534c0ea36b94 + reqSigs: 1 + type: witness_v0_keyhash + addresses: + - bc1qf0exqpamvfjr804n9arf38znfs82x6u5y6knw2 + - value: 0.00299666 + 'n': 38 + scriptPubKey: + asm: OP_HASH160 fec8bce62d0b8caf0881ce3596c1ca37d48df3ef OP_EQUAL + hex: a914fec8bce62d0b8caf0881ce3596c1ca37d48df3ef87 + reqSigs: 1 + type: scripthash + addresses: + - 3QvC2nHZAN2PyPZB7udefhoV3etnRzNG2H + - value: 0.06105704 + 'n': 39 + scriptPubKey: + asm: 0 715f70274118762b58a11dcfbff636faa4be8a3d + hex: 0014715f70274118762b58a11dcfbff636faa4be8a3d + reqSigs: 1 + type: witness_v0_keyhash + addresses: + - bc1qw90hqf6prpmzkk9prh8mla3kl2jtaz3annek34 + - value: 0.00071196 + 'n': 40 + scriptPubKey: + asm: >- + OP_DUP OP_HASH160 cac8f77da9673a862a29d6e24f9a0a3b4d6285d0 + OP_EQUALVERIFY OP_CHECKSIG + hex: 76a914cac8f77da9673a862a29d6e24f9a0a3b4d6285d088ac + reqSigs: 1 + type: pubkeyhash + addresses: + - 1KVEFAaRWQthRqABrZV7eQSiHVEhmrzc9z + - value: 0.01467459 + 'n': 41 + scriptPubKey: + asm: OP_HASH160 4c79e8d15a93ef96ffe849ff1d013907a71f29cb OP_EQUAL + hex: a9144c79e8d15a93ef96ffe849ff1d013907a71f29cb87 + reqSigs: 1 + type: scripthash + addresses: + - 38fPKYFMFjETnk2h3QHqZoRtHyWbHKtKxC + - value: 0.00275465 + 'n': 42 + scriptPubKey: + asm: >- + OP_DUP OP_HASH160 93d66c36e24f6750c3b1f714d26ccc06e30f8c0c + OP_EQUALVERIFY OP_CHECKSIG + hex: 76a91493d66c36e24f6750c3b1f714d26ccc06e30f8c0c88ac + reqSigs: 1 + type: pubkeyhash + addresses: + - 1EUhCYvGuGYEXKwBcJkdzm1wppUpsLNzfp + - value: 0.001413 + 'n': 43 + scriptPubKey: + asm: >- + OP_DUP OP_HASH160 670d8e194515294a39ca836bcd89c5e63946ad77 + OP_EQUALVERIFY OP_CHECKSIG + hex: 76a914670d8e194515294a39ca836bcd89c5e63946ad7788ac + reqSigs: 1 + type: pubkeyhash + addresses: + - 1APtqajF3AqK9m4jHnF5ycJZUoGJET5fn9 + - value: 0.00096567 + 'n': 44 + scriptPubKey: + asm: >- + OP_DUP OP_HASH160 bd744f75e1051670b45ea769f2807ce42ffc3760 + OP_EQUALVERIFY OP_CHECKSIG + hex: 76a914bd744f75e1051670b45ea769f2807ce42ffc376088ac + reqSigs: 1 + type: pubkeyhash + addresses: + - 1JGk3eLP6cnTMpVewxo635epPfwpFVwYJe + - value: 0.00020986 + 'n': 45 + scriptPubKey: + asm: >- + OP_DUP OP_HASH160 a2f869675fc607b7e32c21536b8882781057f3a7 + OP_EQUALVERIFY OP_CHECKSIG + hex: 76a914a2f869675fc607b7e32c21536b8882781057f3a788ac + reqSigs: 1 + type: pubkeyhash + addresses: + - 1Fri42XhTqUo9oZYH7tVfkxBEDgeuRk9r4 + - value: 0.00605577 + 'n': 46 + scriptPubKey: + asm: OP_HASH160 0cbf435d9f011cf09c193a18c2c69c8c1319d5e0 OP_EQUAL + hex: a9140cbf435d9f011cf09c193a18c2c69c8c1319d5e087 + reqSigs: 1 + type: scripthash + addresses: + - 32rRA3Q7Ao2LfXEHJQF4zuXTh4McSMop3i + - value: 0.00514602 + 'n': 47 + scriptPubKey: + asm: OP_HASH160 72b85f3d0b3091ffe3e1e33499bc850cb2e1bb62 OP_EQUAL + hex: a91472b85f3d0b3091ffe3e1e33499bc850cb2e1bb6287 + reqSigs: 1 + type: scripthash + addresses: + - 3C9bpofL67kQRNuLcu69W5oCJZB31uUPqz + - value: 0.00932193 + 'n': 48 + scriptPubKey: + asm: >- + OP_DUP OP_HASH160 9fd915599b7f06b822f0296bd90abacd129f4f76 + OP_EQUALVERIFY OP_CHECKSIG + hex: 76a9149fd915599b7f06b822f0296bd90abacd129f4f7688ac + reqSigs: 1 + type: pubkeyhash + addresses: + - 1FaCVim4b3m1XhbYKwKL7yjfABRbXzWNGK + - value: 0.01506707 + 'n': 49 + scriptPubKey: + asm: OP_HASH160 8f9ef19321ad0a62eeb1034ffc41303658095a91 OP_EQUAL + hex: a9148f9ef19321ad0a62eeb1034ffc41303658095a9187 + reqSigs: 1 + type: scripthash + addresses: + - 3EnQxaFCbzYMLM2Qbp5NycaydkSSpSmqir + hex: >- + 010000000001019e3c5f66d7d0519b53491fd5184a8c962dbef84f5e28197959815c5fbedb8d4d3b00000000ffffffff32ee6a2e00000000001976a914c378ded906a60a72b6345b5eaff0d933427218a588ac7c0a180000000000160014cb60668f051c001353e14e4218806911879e934ef41d04000000000017a91453e13860d18555d9d2d595c8df33823a177d40ee87e72e16000000000017a91402de054ac7322088ff02f28d09f4e24653e870b7875d1f0500000000001976a9146b6c4f33d3931c52cc3760e0e864ac905b5aafb088ac902702000000000017a91403c04e312012941bbc2941e2a1c9e1db3f58e741876cd401000000000017a9144eb5ef7073cfa46e1dcbd432e5461169b69d87d18777de00000000000017a9148b219ff8975fdc4e92e99f2adc52396cf86d23b087e04e0000000000001976a9149a716a4e526dc3e1ff3d8fdb9513d21a584bb41f88ac7b670600000000001976a914e739159436dcac622b027fc8fe03266a940ec82188ac563001000000000017a9145e683f3531dc04fbfd40f77375e920d5d241a95487930a0100000000001976a9147762c98e0e3367094084716de9c539d489e6441788ac283a0900000000001976a91408f99e916e4cf152e6a241c05c79cedc0908486488ac747e06000000000017a914d3f1766bf4170e8491e522abc5f403c8c5b00cb387a25504000000000017a914af3ed025d98feaf94600c016bc71023edc305273871d2609000000000017a9147fc5ada0ec0d456d5c5b58fd21b7968bdd7a02df876efb5f000000000017a914e0e95aacb6866119226c2b391fbb8e165e1b9c87876bd00000000000001976a91451564fb5db5530ec7d6fa333647a01af7380d21788ac2f5cab000000000017a9149501fed908d5114cedd9386660873e62ca2f3dff8745da06000000000017a914b83032f7d5cca0051f788f1a2eff90ab2d79e3d48720cd0800000000001976a914eeb8bacc9220f59abb663e432985ee200d427f3088ace2580400000000001600144a12310c411a22a565621fa258e8426bd7c8d0b3e09304000000000017a914d5d8c6caf78fc21061fc4731c24b0c89a36c7ad687f82401000000000017a9148289e1a729717438ebcdf8c9e07596ec2d3acbaa8761610400000000001976a9146451b87e24ca86905eea9d851e28c5b8aa9dee3988aca4900200000000001976a914d37556e83e286f550870db5c825e6fffc312e55588ac8e3a000000000000160014353b138c3be7387ddc491c83e7159d736c537de1c4240100000000001976a914845c12e6aedc4cdbc79f2eacce9ca30d631b9aa788acb43f0100000000001976a9140e09830988a068eb6507dbae420639dd881b47c488aca0900200000000001976a9147e66edc27e301deb97e19ce70e4204ea670196e188ac473601000000000017a914168046f69a90adcf31e4ed4dd580b643894f3815879cda2b000000000016001423b91d13fd85c250078bef3e696141afbc7d67d7af5d0000000000001976a91481316d20a965c57e365ddbd88cf0b33df182497c88accadb00000000000017a91440aa6e55061da5ef2b270b375d169df7d578785a87805804000000000017a91471084b0c6799c2db9ad5ba2afd88af69cfaf38db87af5d5600000000001976a914fd61259381494884b2094a6c7e015ecf964dcedb88ac80580400000000001976a914d3e27eac3b18ab2fe0e543b0e24a457aba4508a788ac8b3a0000000000001600144bf26007bb626433beb32f46989c534c0ea36b94929204000000000017a914fec8bce62d0b8caf0881ce3596c1ca37d48df3ef87682a5d0000000000160014715f70274118762b58a11dcfbff636faa4be8a3d1c160100000000001976a914cac8f77da9673a862a29d6e24f9a0a3b4d6285d088ac436416000000000017a9144c79e8d15a93ef96ffe849ff1d013907a71f29cb8709340400000000001976a91493d66c36e24f6750c3b1f714d26ccc06e30f8c0c88acf4270200000000001976a914670d8e194515294a39ca836bcd89c5e63946ad7788ac37790100000000001976a914bd744f75e1051670b45ea769f2807ce42ffc376088acfa510000000000001976a914a2f869675fc607b7e32c21536b8882781057f3a788ac893d09000000000017a9140cbf435d9f011cf09c193a18c2c69c8c1319d5e0872ada07000000000017a91472b85f3d0b3091ffe3e1e33499bc850cb2e1bb628761390e00000000001976a9149fd915599b7f06b822f0296bd90abacd129f4f7688ac93fd16000000000017a9148f9ef19321ad0a62eeb1034ffc41303658095a91870248304502210089ca3893f1180326d1bbc27f89b23ce5e2ef4f35c9130eaff088f0484896c08f02205559db4a068aaa1547972e18ce77181de04206e8d2e2a4b2bfcff6a531cce199012102efd56b2aa9c332bafdadee106a21d3feea0e93e83b2c01e30172719b5e5a0e0b00000000 + - txid: 826bf9e346ae54290d238c12226c130bcf813fe533e858fc1e083b9f983db6e9 + hash: 5108a3ef46617187688bfbb50beb3876c0cddb9aa885a199ba67d62d2c7831ef + version: 2 + size: 191 + vsize: 110 + weight: 437 + locktime: 0 + vin: + - txid: fd2c4bfc533daf07a3a3a4b48727330b3d0df03b8d10bfb6f2c44ea6f375869a + vout: 0 + scriptSig: + asm: '' + hex: '' + txinwitness: + - >- + 304402203822f1f9b7908e8e80b3cb4a655cb80425feaa04319098af909d640bfc07e5a30220071eeed6e1f86a8fba49c6d29eeec5487bcf3c8d6833d0c181d41baa374ce95001 + - 02de8829afb19976f347b0f0b6fc27117abba6a336366aa16c0ffa6fc4a456afb6 + sequence: 4294967295 + vout: + - value: 0.00662213 + 'n': 0 + scriptPubKey: + asm: 0 6c18ac26595dd955b85b174a3d8c78e387071e8c + hex: 00146c18ac26595dd955b85b174a3d8c78e387071e8c + reqSigs: 1 + type: witness_v0_keyhash + addresses: + - bc1qdsv2cfjethv4twzmza9rmrrcuwrsw85ve9mx6c + hex: >- + 020000000001019a8675f3a64ec4f2b6bf108d3bf00d3d0b332787b4a4a3a307af3d53fc4b2cfd0000000000ffffffff01c51a0a00000000001600146c18ac26595dd955b85b174a3d8c78e387071e8c0247304402203822f1f9b7908e8e80b3cb4a655cb80425feaa04319098af909d640bfc07e5a30220071eeed6e1f86a8fba49c6d29eeec5487bcf3c8d6833d0c181d41baa374ce950012102de8829afb19976f347b0f0b6fc27117abba6a336366aa16c0ffa6fc4a456afb600000000 + - txid: 1b66512cd7c982b495fee0bd46662a8ce285f782961c8cac951c0717f64f93c8 + hash: 81e43574e4093f75e0c7188885b1a9b5da2a764fc681fe40c0fdae34f2b99474 + version: 1 + size: 404 + vsize: 214 + weight: 854 + locktime: 690097 + vin: + - txid: 211e183e2b04c4c56ec1ad1f5bb31ffd69c5eeae22c4fd5a83b4f691c52679e8 + vout: 1 + scriptSig: + asm: 00201050f81f3cf192e8c5f1923700e7fa222aa2d4845303a4087f019408d972fd12 + hex: >- + 2200201050f81f3cf192e8c5f1923700e7fa222aa2d4845303a4087f019408d972fd12 + txinwitness: + - '' + - >- + 30440220077cd1a4eda2fd2251bb4e88fe9cb9abe73c40244c61916e54e19425ec38f43f02204c2ead8de4a7f7e537e2b71a0dd831d20d6f8fbfd0ad957221832f1a5ee884de01 + - >- + 30440220187cc4f3f86a1fdb8dd9e688f85568bab932e4347fef9e1f052a8e68497808530220328c1918fec26d10a81d938bbb5f708eacd39884d57e60e0fa23ebad1c530e9301 + - >- + 5221036414da3ee01031b225fff42f958db3f35064540a820a46dea3c5af79b1ef6a352102fae595ff8c0a41acbd2533e211a0236626b903472dab1c79cd3101c856d01faf2102c94ac1e83cd87f7566251b51112e20d79c69cc6d6bfcd5b3cbba3428b6ef2b8653ae + sequence: 4294967295 + vout: + - value: 0.01522308 + 'n': 0 + scriptPubKey: + asm: OP_HASH160 dfb610f26c86fbaab363c3b264bb283facabaa58 OP_EQUAL + hex: a914dfb610f26c86fbaab363c3b264bb283facabaa5887 + reqSigs: 1 + type: scripthash + addresses: + - 3N5tiW96XeYngeJ8hrNL63p4Ja1JiUbFud + - value: 2.24037374 + 'n': 1 + scriptPubKey: + asm: OP_HASH160 f02f35dfd649ccfdbb1e9a19156c3fb99a0d13ad OP_EQUAL + hex: a914f02f35dfd649ccfdbb1e9a19156c3fb99a0d13ad87 + reqSigs: 1 + type: scripthash + addresses: + - 3PazepeokvQxDiSvrwmEKAoEALgTBYkMsL + hex: >- + 01000000000101e87926c591f6b4835afdc422aeeec569fd1fb35b1fadc16ec5c4042b3e181e2101000000232200201050f81f3cf192e8c5f1923700e7fa222aa2d4845303a4087f019408d972fd12ffffffff02843a17000000000017a914dfb610f26c86fbaab363c3b264bb283facabaa5887fe895a0d0000000017a914f02f35dfd649ccfdbb1e9a19156c3fb99a0d13ad8704004730440220077cd1a4eda2fd2251bb4e88fe9cb9abe73c40244c61916e54e19425ec38f43f02204c2ead8de4a7f7e537e2b71a0dd831d20d6f8fbfd0ad957221832f1a5ee884de014730440220187cc4f3f86a1fdb8dd9e688f85568bab932e4347fef9e1f052a8e68497808530220328c1918fec26d10a81d938bbb5f708eacd39884d57e60e0fa23ebad1c530e9301695221036414da3ee01031b225fff42f958db3f35064540a820a46dea3c5af79b1ef6a352102fae595ff8c0a41acbd2533e211a0236626b903472dab1c79cd3101c856d01faf2102c94ac1e83cd87f7566251b51112e20d79c69cc6d6bfcd5b3cbba3428b6ef2b8653aeb1870a00 + - txid: 217e4dce0fab15ab73dd2e36f9b83ec5d68795788af5491672613b704e2c0578 + hash: 95bfe71c714e843da0f6bd8d62f2a88c588c0187676f17865c6ad26ea7ff5b10 + version: 2 + size: 214 + vsize: 133 + weight: 529 + locktime: 690097 + vin: + - txid: 08d7b7e20593ea2691f0a8df5e9d9ebdb5b417e960ea103b827d022222a2b3a5 + vout: 0 + scriptSig: + asm: 0014d8e7dfd2980abb8a17160af2eb778bed171f51a4 + hex: 160014d8e7dfd2980abb8a17160af2eb778bed171f51a4 + txinwitness: + - >- + 304402204c5b54e1026e7b8e424d10a1e7fe55c5268e27350beeb3195e3e92623ba1c14f02207448cca3450a71f5ca7cbbbf95e6022afdc964642f6f0bc8f0513677e8373eb901 + - 021b1654ea4843ddfbf7c2c9bbdd0add4f81c1789b4531739c07bc169b7a523bc8 + sequence: 4294967294 + vout: + - value: 0.0035976 + 'n': 0 + scriptPubKey: + asm: 0 1d4f2ad2a9e6d7ddd83469425ff59441e4f9eb23 + hex: 00141d4f2ad2a9e6d7ddd83469425ff59441e4f9eb23 + reqSigs: 1 + type: witness_v0_keyhash + addresses: + - bc1qr48j454fumtamkp5d9p9lav5g8j0n6erdrfucw + hex: >- + 02000000000101a5b3a22222027d823b10ea60e917b4b5bd9e9d5edfa8f09126ea9305e2b7d7080000000017160014d8e7dfd2980abb8a17160af2eb778bed171f51a4feffffff01507d0500000000001600141d4f2ad2a9e6d7ddd83469425ff59441e4f9eb230247304402204c5b54e1026e7b8e424d10a1e7fe55c5268e27350beeb3195e3e92623ba1c14f02207448cca3450a71f5ca7cbbbf95e6022afdc964642f6f0bc8f0513677e8373eb90121021b1654ea4843ddfbf7c2c9bbdd0add4f81c1789b4531739c07bc169b7a523bc8b1870a00 + - txid: 58bce502ea68bcd555d9e436404e82113dfc887f6d0af11f973e38d619c34389 + hash: 964527b894b9572a2a343ee9ab3290e3fd6cc5bf6572c9e0228fecaa345d8435 + version: 1 + size: 226 + vsize: 144 + weight: 574 + locktime: 0 + vin: + - txid: ccb2592f7ee5f59f663416d466fb4af5cf77df6021211c6e451766bc29ce8163 + vout: 1 + scriptSig: + asm: '' + hex: '' + txinwitness: + - >- + 3045022100c8f748b7101f2ff35c4a80be66e31e131f19c889993e3b1980c4e87bf049b91e0220432099cdc708c333a1c8a79632b01762a7b10cbc2224d0f2f64ef896e7e9810801 + - 03d9ac44f61276f12807d3a66711d4a9b385fab4fd24e61b67de3610d5bbbc4d58 + sequence: 4294967294 + vout: + - value: 0.00029956 + 'n': 0 + scriptPubKey: + asm: >- + OP_DUP OP_HASH160 0f30034977561e424564ce8eca6554f721693f06 + OP_EQUALVERIFY OP_CHECKSIG + hex: 76a9140f30034977561e424564ce8eca6554f721693f0688ac + reqSigs: 1 + type: pubkeyhash + addresses: + - 12PJesM7FM9zg6k9byhGjFTGTxfC5RDtwY + - value: 0.00009794 + 'n': 1 + scriptPubKey: + asm: 0 ce5bd11f4c403d73717538794d0d9c333c82585c + hex: 0014ce5bd11f4c403d73717538794d0d9c333c82585c + reqSigs: 1 + type: witness_v0_keyhash + addresses: + - bc1qeedaz86vgq7hxut48pu56rvuxv7gykzudlkt8f + hex: >- + 010000000001016381ce29bc6617456e1c212160df77cff54afb66d41634669ff5e57e2f59b2cc0100000000feffffff0204750000000000001976a9140f30034977561e424564ce8eca6554f721693f0688ac4226000000000000160014ce5bd11f4c403d73717538794d0d9c333c82585c02483045022100c8f748b7101f2ff35c4a80be66e31e131f19c889993e3b1980c4e87bf049b91e0220432099cdc708c333a1c8a79632b01762a7b10cbc2224d0f2f64ef896e7e98108012103d9ac44f61276f12807d3a66711d4a9b385fab4fd24e61b67de3610d5bbbc4d5800000000 + - txid: f7a194e852d405fb98b665345bf9ec0ab0a5c4ac7ee3a44e9423494881e40ee9 + hash: 86a2a9ab8d33605de904c1465599f66c1269c59b8106488089a36bd2eae06ee8 + version: 1 + size: 224 + vsize: 142 + weight: 566 + locktime: 0 + vin: + - txid: 63bddc99cb614942b367ef9f9ad86e95c972cd5309c1990f99f8435c8b182a87 + vout: 19 + scriptSig: + asm: '' + hex: '' + txinwitness: + - >- + 3045022100f2d38235d74912cfad18a1bbb834c29a330f15675b159157749a9c88d31816b602206a161222a42ede172d15c88141d812003dfdbe519108a94bcbbbe831a07e4b1001 + - 0330d24edc6c5646162672257ba2689297ecbc59c8005952f6aea51198df520d6c + sequence: 0 + vout: + - value: 0.00005991 + 'n': 0 + scriptPubKey: + asm: OP_HASH160 c1e70061f0c8d24dcf42b1dd3ee7749c841118ba OP_EQUAL + hex: a914c1e70061f0c8d24dcf42b1dd3ee7749c841118ba87 + reqSigs: 1 + type: scripthash + addresses: + - 3KNH4qDuaYVtHbC3DJgCo26jMfVWJGd1ac + - value: 0.34677699 + 'n': 1 + scriptPubKey: + asm: 0 26da8ead36f9cb7232885e24bed55db638983b83 + hex: 001426da8ead36f9cb7232885e24bed55db638983b83 + reqSigs: 1 + type: witness_v0_keyhash + addresses: + - bc1qymdgatfkl89hyv5gtcjta42akcufswurm60a6k + hex: >- + 01000000000101872a188b5c43f8990f99c10953cd72c9956ed89a9fef67b3424961cb99dcbd6313000000000000000002671700000000000017a914c1e70061f0c8d24dcf42b1dd3ee7749c841118ba87c32311020000000016001426da8ead36f9cb7232885e24bed55db638983b8302483045022100f2d38235d74912cfad18a1bbb834c29a330f15675b159157749a9c88d31816b602206a161222a42ede172d15c88141d812003dfdbe519108a94bcbbbe831a07e4b1001210330d24edc6c5646162672257ba2689297ecbc59c8005952f6aea51198df520d6c00000000 + - txid: a68dbd1477862e3bebbfde019aeda36a513cadd06f046f266a1d1b5ba0b9bbff + hash: a68dbd1477862e3bebbfde019aeda36a513cadd06f046f266a1d1b5ba0b9bbff + version: 1 + size: 226 + vsize: 226 + weight: 904 + locktime: 0 + vin: + - txid: fe27bcb0e186bbc9af21b4c4221a2dee8c8f6abb24f8722fc6d76626bddd96bb + vout: 1 + scriptSig: + asm: >- + 3045022100b3299607ff35cfbc2017b1841aa3d31c27f9135a008b949481357c013e061d560220748e3af715112ac5ac189a1328ede5b98f157ca6fd62d50f691a5c1b6698c4c2[ALL] + 031e9a636ef528970636cc811384ffde2a2c6d131a67d02e8e082b0c09c1669f54 + hex: >- + 483045022100b3299607ff35cfbc2017b1841aa3d31c27f9135a008b949481357c013e061d560220748e3af715112ac5ac189a1328ede5b98f157ca6fd62d50f691a5c1b6698c4c20121031e9a636ef528970636cc811384ffde2a2c6d131a67d02e8e082b0c09c1669f54 + sequence: 1 + vout: + - value: 0.00450316 + 'n': 0 + scriptPubKey: + asm: >- + OP_DUP OP_HASH160 b1da96c6d9f8ca1df601b6f0b375cca783a4de42 + OP_EQUALVERIFY OP_CHECKSIG + hex: 76a914b1da96c6d9f8ca1df601b6f0b375cca783a4de4288ac + reqSigs: 1 + type: pubkeyhash + addresses: + - 1HDQTnMejNiaJMjqKHpnak2B3snQBxoM38 + - value: 0.44870761 + 'n': 1 + scriptPubKey: + asm: >- + OP_DUP OP_HASH160 1e7c72c338f790b929422397218d8785a4aeda61 + OP_EQUALVERIFY OP_CHECKSIG + hex: 76a9141e7c72c338f790b929422397218d8785a4aeda6188ac + reqSigs: 1 + type: pubkeyhash + addresses: + - 13nCMaHDNRGM29UfMMkhUQjHkVYY1ZyrpU + hex: >- + 0100000001bb96ddbd2666d7c62f72f824bb6a8f8cee2d1a22c4b421afc9bb86e1b0bc27fe010000006b483045022100b3299607ff35cfbc2017b1841aa3d31c27f9135a008b949481357c013e061d560220748e3af715112ac5ac189a1328ede5b98f157ca6fd62d50f691a5c1b6698c4c20121031e9a636ef528970636cc811384ffde2a2c6d131a67d02e8e082b0c09c1669f5401000000020cdf0600000000001976a914b1da96c6d9f8ca1df601b6f0b375cca783a4de4288ac69acac02000000001976a9141e7c72c338f790b929422397218d8785a4aeda6188ac00000000 + - txid: ce91e574fec8d49959ec2b6772fbc57b39e863ca1f7533775cb428d68b686fef + hash: b878fadfd59cc6944b08f3ab38820ee6d6d69942bd092efca58957d2b2987f37 + version: 2 + size: 557 + vsize: 315 + weight: 1259 + locktime: 690097 + vin: + - txid: 7dc40d7136d6c08ee1f57910e42e670691b44002f8243c1faf4554778b99a6b8 + vout: 415 + scriptSig: + asm: 001469c11bcdbf3462cf93c59b8005afcf0b524eabf0 + hex: 16001469c11bcdbf3462cf93c59b8005afcf0b524eabf0 + txinwitness: + - >- + 30440220531ce32754eb3f2a514e222d2f2cb831f07caba2f6ea6ca6ac5728f64b69ac4202204e20882cfe413982a6a04464487c7b7794f2f9bfd90743d18668378bc4be91f501 + - 03abc33ddacdf49de4b23dd1129d09447ceb65c63d53fde522eda5ea02769548a9 + sequence: 4294967293 + - txid: 7dc40d7136d6c08ee1f57910e42e670691b44002f8243c1faf4554778b99a6b8 + vout: 2836 + scriptSig: + asm: 0014b016e01e92bf06c9be72807ac0fc4bc7019f7f30 + hex: 160014b016e01e92bf06c9be72807ac0fc4bc7019f7f30 + txinwitness: + - >- + 30440220053eefd97e286c0c36713642f4845e19e4cdde2ef69dc598fe075c034b291cc702204149106ea978b851607830d937900c2c72a84b07244ae3341f12061139c190a801 + - 0210527396e491eadb17a4fb4a8c8f565c1479df2792ed9ac054e88deb8e263fb0 + sequence: 4294967293 + - txid: d3bfad4f2b53c4dc34daa6bcffaaea1b06499b090145df2a47d160504db54b9c + vout: 43 + scriptSig: + asm: 0014de89107b16de1d796cfedc3504dad23319499db9 + hex: 160014de89107b16de1d796cfedc3504dad23319499db9 + txinwitness: + - >- + 3044022014ab0be12a8adf968e9a4491588cbc1d253be126a77c615a3d9fb6fd31de2d3e02207f03060c5fe44081d2b19ca6688e71e03d611bbfe516310cd711de5b3659b41701 + - 02c2faa9505090a725080ef731b099fd38b525b14c291c78dc9c15d8355bdc91a9 + sequence: 4294967293 + vout: + - value: 0.03014448 + 'n': 0 + scriptPubKey: + asm: OP_HASH160 cf3fd4edf20dc374e92523385f306553c0a43dd1 OP_EQUAL + hex: a914cf3fd4edf20dc374e92523385f306553c0a43dd187 + reqSigs: 1 + type: scripthash + addresses: + - 3LarGMsxpFbbMANJ2nTSG8RmquyiGfKDP3 + hex: >- + 02000000000103b8a6998b775445af1f3c24f80240b49106672ee41079f5e18ec0d636710dc47d9f0100001716001469c11bcdbf3462cf93c59b8005afcf0b524eabf0fdffffffb8a6998b775445af1f3c24f80240b49106672ee41079f5e18ec0d636710dc47d140b000017160014b016e01e92bf06c9be72807ac0fc4bc7019f7f30fdffffff9c4bb54d5060d1472adf4501099b49061beaaaffbca6da34dcc4532b4fadbfd32b00000017160014de89107b16de1d796cfedc3504dad23319499db9fdffffff0130ff2d000000000017a914cf3fd4edf20dc374e92523385f306553c0a43dd187024730440220531ce32754eb3f2a514e222d2f2cb831f07caba2f6ea6ca6ac5728f64b69ac4202204e20882cfe413982a6a04464487c7b7794f2f9bfd90743d18668378bc4be91f5012103abc33ddacdf49de4b23dd1129d09447ceb65c63d53fde522eda5ea02769548a9024730440220053eefd97e286c0c36713642f4845e19e4cdde2ef69dc598fe075c034b291cc702204149106ea978b851607830d937900c2c72a84b07244ae3341f12061139c190a801210210527396e491eadb17a4fb4a8c8f565c1479df2792ed9ac054e88deb8e263fb002473044022014ab0be12a8adf968e9a4491588cbc1d253be126a77c615a3d9fb6fd31de2d3e02207f03060c5fe44081d2b19ca6688e71e03d611bbfe516310cd711de5b3659b417012102c2faa9505090a725080ef731b099fd38b525b14c291c78dc9c15d8355bdc91a9b1870a00 + - txid: 322a50eb82656e81082572155771948a1903a808b2dfe51688af3ee85519a8f8 + hash: 6e61a2bf03f2ef32be80896852e1fb38911e18fef94f3eafc0674c40557e8dfd + version: 2 + size: 247 + vsize: 166 + weight: 661 + locktime: 690097 + vin: + - txid: 451e064698ec1e0c2a1bf1c88cf18afd94e43cca26d16b2486b87269f26b646f + vout: 0 + scriptSig: + asm: 001480090cde8f2563879e0108a6b729178c4ff91d7a + hex: 16001480090cde8f2563879e0108a6b729178c4ff91d7a + txinwitness: + - >- + 3044022069ee012d64ed6d2af86a0cc318a419218717b9d4607fb6da3fd4233e7ef44b7e022002c769b0b9bd3d664849e73868d77efc4addbe1d41c242d901338a5e6b73a7b201 + - 02dbc646d2d44ec390542a4abd6902c387afa9e4ce559b512343ed691fc481d8a1 + sequence: 4294967293 + vout: + - value: 0.00305021 + 'n': 0 + scriptPubKey: + asm: OP_HASH160 3831317df36b605e41b860c0ac218542cd85808a OP_EQUAL + hex: a9143831317df36b605e41b860c0ac218542cd85808a87 + reqSigs: 1 + type: scripthash + addresses: + - 36p8hJGoDuobgVSpAomNmjihD4wwLj4P3t + - value: 17.00925009 + 'n': 1 + scriptPubKey: + asm: OP_HASH160 1ba7a9a53c05d26a6983f216f4d1205634ac80fd OP_EQUAL + hex: a9141ba7a9a53c05d26a6983f216f4d1205634ac80fd87 + reqSigs: 1 + type: scripthash + addresses: + - 34DF28WNaM7UMG337WhWdaPoENBqgNq9LB + hex: >- + 020000000001016f646bf26972b886246bd126ca3ce494fd8af18cc8f11b2a0c1eec9846061e45000000001716001480090cde8f2563879e0108a6b729178c4ff91d7afdffffff027da704000000000017a9143831317df36b605e41b860c0ac218542cd85808a87510e62650000000017a9141ba7a9a53c05d26a6983f216f4d1205634ac80fd8702473044022069ee012d64ed6d2af86a0cc318a419218717b9d4607fb6da3fd4233e7ef44b7e022002c769b0b9bd3d664849e73868d77efc4addbe1d41c242d901338a5e6b73a7b2012102dbc646d2d44ec390542a4abd6902c387afa9e4ce559b512343ed691fc481d8a1b1870a00 + - txid: 4aaf9baf14a22f6a506d5b3ed98206c526e1f34f96ff33eab4ed5ac47c0c6d99 + hash: 98457850996ca405112e309da2c7607dfb67795d47e2d7b654ba1307f3d01d74 + version: 1 + size: 374 + vsize: 292 + weight: 1166 + locktime: 0 + vin: + - txid: 7a6a4b807505b052921e54da86b6ff685e7dda6c0894f7397bd60395eafed6f9 + vout: 21 + scriptSig: + asm: >- + 3045022100b0e1f5e48421310cc6ae7ab8aeb701ae2aa3529da7707355f3783ba7f83f10c002203305e035234f70d40a2d734520c10eaa96fa2e102f38bceb172a64fbf9291a94[ALL] + 02e68bd9ba1d05767adf0c3033c4a6466f815ad597e14ff85cfafc75570ffa1245 + hex: >- + 483045022100b0e1f5e48421310cc6ae7ab8aeb701ae2aa3529da7707355f3783ba7f83f10c002203305e035234f70d40a2d734520c10eaa96fa2e102f38bceb172a64fbf9291a94012102e68bd9ba1d05767adf0c3033c4a6466f815ad597e14ff85cfafc75570ffa1245 + sequence: 4294967295 + - txid: 1f1633948447a18e2fafa43dc6b9b8a6b0fd99dfad65ef193aeb477769e35124 + vout: 0 + scriptSig: + asm: '' + hex: '' + txinwitness: + - >- + 30440220182c99a1329e72d102c1d82eb6cd09ac563e46384fdea9d7853294ccd7ac2ea902200db86458cc3e9e49904e5f35272015f7b4db7701fe892f38088b3547a0f837a101 + - 02471061ab49123d49c68003fc6aa248d5653415400328ab52b0d1a63b6b13d88c + sequence: 4294967295 + vout: + - value: 0.00007771 + 'n': 0 + scriptPubKey: + asm: 0 10d60ff8a884cd7fd25248d0530bd5af1ddd68b9 + hex: 001410d60ff8a884cd7fd25248d0530bd5af1ddd68b9 + reqSigs: 1 + type: witness_v0_keyhash + addresses: + - bc1qzrtql79gsnxhl5jjfrg9xz744uwa669er26dj8 + - value: 0.02763349 + 'n': 1 + scriptPubKey: + asm: >- + OP_DUP OP_HASH160 1c17013569299a011183890111b8d49fb6038e32 + OP_EQUALVERIFY OP_CHECKSIG + hex: 76a9141c17013569299a011183890111b8d49fb6038e3288ac + reqSigs: 1 + type: pubkeyhash + addresses: + - 13ZXUmWDPJHo5QGy1Mk6e9BSaAMt9M31Wi + hex: >- + 01000000000102f9d6feea9503d67b39f794086cda7d5e68ffb686da541e9252b00575804b6a7a150000006b483045022100b0e1f5e48421310cc6ae7ab8aeb701ae2aa3529da7707355f3783ba7f83f10c002203305e035234f70d40a2d734520c10eaa96fa2e102f38bceb172a64fbf9291a94012102e68bd9ba1d05767adf0c3033c4a6466f815ad597e14ff85cfafc75570ffa1245ffffffff2451e3697747eb3a19ef65addf99fdb0a6b8b9c63da4af2f8ea147849433161f0000000000ffffffff025b1e00000000000016001410d60ff8a884cd7fd25248d0530bd5af1ddd68b9552a2a00000000001976a9141c17013569299a011183890111b8d49fb6038e3288ac00024730440220182c99a1329e72d102c1d82eb6cd09ac563e46384fdea9d7853294ccd7ac2ea902200db86458cc3e9e49904e5f35272015f7b4db7701fe892f38088b3547a0f837a1012102471061ab49123d49c68003fc6aa248d5653415400328ab52b0d1a63b6b13d88c00000000 + - txid: 29d96711529952ec9f46760537e0a778dc7dec4bfa84f869f2b30f62afd6b84f + hash: 066268c41fc718e1432af5c208e76f15bc3650747e6ba87c6d41307bed5f3566 + version: 2 + size: 934 + vsize: 451 + weight: 1804 + locktime: 690097 + vin: + - txid: 4ea698176feac29a081d4b906f887d97123aea766edcdae40fc8acd69e46873c + vout: 2 + scriptSig: + asm: '' + hex: '' + txinwitness: + - >- + 304402200a7201ccebb8eae607f01f1e73dc43022881c8fa4505e5cf7d068dba2d9f10d302206084c24192f6ddbd04b00be4d7addc5d5a6ea2fe3a4734bb3bd021017e4015b801 + - 037bdada249cff349769d9ea6d2efe5d76d1e3beddac5429d735fbe7f6553edcd9 + sequence: 4294967293 + - txid: 824ae16e5526b0c3bc88ba2ce4eb66981dbbfc91c3d3e853720182d34f922e66 + vout: 0 + scriptSig: + asm: '' + hex: '' + txinwitness: + - >- + 304402200e6adcc67185f0f8c12ab99eadd6f36a32f187911af084bd021a6240156ce68f02202d461ea2bc4509145cc11c6f69ab2db67106818b132288be637ca211d6ff024801 + - 0373e81d5ad095408ff305fcc7c2c14c81e6fa962c50fe3ffa1bdc41e1890b17f2 + sequence: 4294967293 + - txid: 82844f219fd63590bde707001d13141a8400e9e1175d3b40306f14ecc033beb5 + vout: 1 + scriptSig: + asm: '' + hex: '' + txinwitness: + - >- + 304402202db1cc195f387ff5dbd4a79fbaeb8e7dd7a4990a3d4c47ad981ca6f3f3768391022068d94d5f29552765be2e311ddf6761e54f378f9414602b913f7c56076faecf2c01 + - 03cd29ef645c1948fcb04cec63e7a45ccbc8b65497616978b6ea8ae13fe4687bf7 + sequence: 4294967293 + - txid: beda79db1b8a5e4f50b29112a33c6d7704e8f48da96a04fb82b0a49c1b50cfe5 + vout: 0 + scriptSig: + asm: '' + hex: '' + txinwitness: + - >- + 304402201dbc1edb23acc6adcf6e631822d4abd4f797055bce1e65cbcc428f75757b853202201f958da9d493f2ab806d58fdd68e8f6c29274d29d0b8ebe72d73acf52ab986db01 + - 0273e4e29485a8da1af6695d4139d256b79e58aec75e75c77143f5241018ae821d + sequence: 4294967293 + - txid: ceba7a41bc03ed7d63106e3e1e0a3eef2a9feab9fdee31aa1337037a93fc54be + vout: 1 + scriptSig: + asm: '' + hex: '' + txinwitness: + - >- + 304402200760498a6bb830bb8ae89db766df42e9ac64728687f9e91bcacb77af0fe5d06a02206a808a0c60b894677a149f99ffad087aa1b9f17fe238c11ddbbf6b1a6fb9a34101 + - 033461ad224af04730d6fdfabca98252076c3ae3806fca31caa878f08458aa38cc + sequence: 4294967293 + - txid: dbdc55a55ae77b2f532360933ea8f666a6e3641d6f300477e18c4881c7836b02 + vout: 1 + scriptSig: + asm: '' + hex: '' + txinwitness: + - >- + 3044022004803fb767a77e55bb5d7911f43b890ce63173a20c8083927cba1c63e624d406022054dfed5ae4b5aba3cc46da6f3d1a066ff336d252e54742f85f44d96b24243f0101 + - 02063a9e0afe23cc732864101599f8d07be84228f89f838bff29494075f02f39da + sequence: 4294967293 + vout: + - value: 0.03112855 + 'n': 0 + scriptPubKey: + asm: >- + OP_DUP OP_HASH160 561c8f5dcb731ccb9af98393fa0e2dbfbefd7aee + OP_EQUALVERIFY OP_CHECKSIG + hex: 76a914561c8f5dcb731ccb9af98393fa0e2dbfbefd7aee88ac + reqSigs: 1 + type: pubkeyhash + addresses: + - 18rKKtCXjqEkLZ5VBAMFm78yEur5wgkVaP + hex: >- + 020000000001063c87469ed6acc80fe4dadc6e76ea3a12977d886f904b1d089ac2ea6f1798a64e0200000000fdffffff662e924fd382017253e8d3c391fcbb1d9866ebe42cba88bcc3b026556ee14a820000000000fdffffffb5be33c0ec146f30403b5d17e1e900841a14131d0007e7bd9035d69f214f84820100000000fdffffffe5cf501b9ca4b082fb046aa98df4e804776d3ca31291b2504f5e8a1bdb79dabe0000000000fdffffffbe54fc937a033713aa31eefdb9ea9f2aef3e0a1e3e6e10637ded03bc417abace0100000000fdffffff026b83c781488ce17704306f1d64e3a666f6a83e936023532f7be75aa555dcdb0100000000fdffffff01977f2f00000000001976a914561c8f5dcb731ccb9af98393fa0e2dbfbefd7aee88ac0247304402200a7201ccebb8eae607f01f1e73dc43022881c8fa4505e5cf7d068dba2d9f10d302206084c24192f6ddbd04b00be4d7addc5d5a6ea2fe3a4734bb3bd021017e4015b80121037bdada249cff349769d9ea6d2efe5d76d1e3beddac5429d735fbe7f6553edcd90247304402200e6adcc67185f0f8c12ab99eadd6f36a32f187911af084bd021a6240156ce68f02202d461ea2bc4509145cc11c6f69ab2db67106818b132288be637ca211d6ff024801210373e81d5ad095408ff305fcc7c2c14c81e6fa962c50fe3ffa1bdc41e1890b17f20247304402202db1cc195f387ff5dbd4a79fbaeb8e7dd7a4990a3d4c47ad981ca6f3f3768391022068d94d5f29552765be2e311ddf6761e54f378f9414602b913f7c56076faecf2c012103cd29ef645c1948fcb04cec63e7a45ccbc8b65497616978b6ea8ae13fe4687bf70247304402201dbc1edb23acc6adcf6e631822d4abd4f797055bce1e65cbcc428f75757b853202201f958da9d493f2ab806d58fdd68e8f6c29274d29d0b8ebe72d73acf52ab986db01210273e4e29485a8da1af6695d4139d256b79e58aec75e75c77143f5241018ae821d0247304402200760498a6bb830bb8ae89db766df42e9ac64728687f9e91bcacb77af0fe5d06a02206a808a0c60b894677a149f99ffad087aa1b9f17fe238c11ddbbf6b1a6fb9a3410121033461ad224af04730d6fdfabca98252076c3ae3806fca31caa878f08458aa38cc02473044022004803fb767a77e55bb5d7911f43b890ce63173a20c8083927cba1c63e624d406022054dfed5ae4b5aba3cc46da6f3d1a066ff336d252e54742f85f44d96b24243f01012102063a9e0afe23cc732864101599f8d07be84228f89f838bff29494075f02f39dab1870a00 + - txid: f9eb4c381c8dfe47095cf40f846f608fa20923f6b9e50e8db3448ffc6272854d + hash: 2f5733031225dfc8ca2845894d8f97335a9e7f582d7016c388be2c45a3586bdb + version: 1 + size: 407 + vsize: 216 + weight: 863 + locktime: 690097 + vin: + - txid: d9321d6d4eb6e9c9686a982f79c9b3498ca688850a9155e45a6883c95e7cd190 + vout: 2 + scriptSig: + asm: 00204c17874906b9b484cebc0fde0e7c44705050792b90492bafb7d7f732812d3ce2 + hex: >- + 2200204c17874906b9b484cebc0fde0e7c44705050792b90492bafb7d7f732812d3ce2 + txinwitness: + - '' + - >- + 3045022100c0c650cc00bcc79d1f9fcfed118601c51682df4a17981afa6668adfc9804af7802204db5bef84360e19c97abcb2979d866766d5bb7c64a2801994b6b23c8434e4e7701 + - >- + 304402204faa619c7fb1cc4838ed885793cb8f7cbd9520aca90f80047e28ef2214dd2ec3022074dd4fab67a11ce003e92aad6c5daeb2ca52e0d5c81c8a85106479cc205dcda201 + - >- + 522102f86574bbff94767438fd14e8c27e4f074200b351f520cf44cbb182843a3a8d6121033df348ef562e41a2a38c3fc1ccd38a3184c04671f0dd9dd83cb8f0e03ec2708e2102670a229788bd59d537b0379739daeeffaf9fcfe7c411fc8cb785a0a586664fdf53ae + sequence: 4294967295 + vout: + - value: 0.05 + 'n': 0 + scriptPubKey: + asm: >- + OP_DUP OP_HASH160 a250d351fd042f41ab739574b9a2d0578ab624bf + OP_EQUALVERIFY OP_CHECKSIG + hex: 76a914a250d351fd042f41ab739574b9a2d0578ab624bf88ac + reqSigs: 1 + type: pubkeyhash + addresses: + - 1FoFHvrtEdzr7J67v7wgj5rJ9w61xFHarr + - value: 1.39913991 + 'n': 1 + scriptPubKey: + asm: OP_HASH160 a2ac5855a64ba9fe3d808114146e1b440c4b3525 OP_EQUAL + hex: a914a2ac5855a64ba9fe3d808114146e1b440c4b352587 + reqSigs: 1 + type: scripthash + addresses: + - 3GX9rN7L7hoDrwqz2AsBiJcoTszGYmJoA8 + hex: >- + 0100000000010190d17c5ec983685ae455910a8588a68c49b3c9792f986a68c9e9b64e6d1d32d902000000232200204c17874906b9b484cebc0fde0e7c44705050792b90492bafb7d7f732812d3ce2ffffffff02404b4c00000000001976a914a250d351fd042f41ab739574b9a2d0578ab624bf88ac07eb56080000000017a914a2ac5855a64ba9fe3d808114146e1b440c4b3525870400483045022100c0c650cc00bcc79d1f9fcfed118601c51682df4a17981afa6668adfc9804af7802204db5bef84360e19c97abcb2979d866766d5bb7c64a2801994b6b23c8434e4e770147304402204faa619c7fb1cc4838ed885793cb8f7cbd9520aca90f80047e28ef2214dd2ec3022074dd4fab67a11ce003e92aad6c5daeb2ca52e0d5c81c8a85106479cc205dcda20169522102f86574bbff94767438fd14e8c27e4f074200b351f520cf44cbb182843a3a8d6121033df348ef562e41a2a38c3fc1ccd38a3184c04671f0dd9dd83cb8f0e03ec2708e2102670a229788bd59d537b0379739daeeffaf9fcfe7c411fc8cb785a0a586664fdf53aeb1870a00 + - txid: c644b9829782ed1dbdc1e6b298f34e308a643b8c78009457d8c6f5ae5985a304 + hash: c644b9829782ed1dbdc1e6b298f34e308a643b8c78009457d8c6f5ae5985a304 + version: 1 + size: 222 + vsize: 222 + weight: 888 + locktime: 0 + vin: + - txid: c351cff34e8914b52dee5519851b24d6b30edd44db920a1076e353c0c10b86e9 + vout: 2 + scriptSig: + asm: >- + 304402200fadb0b7d19d0aca703a203ba612c3ca72fae86e863947ad7d6ea5cc628050a302204a1a3ee196b09e63ed6201af722d213b8bcdf3b2d935a6610450524bd72d1e8d[ALL] + 02936c15394948d03a7ba3d4a7e7c7523e14194b3ab808cfe5baed526e15bc0651 + hex: >- + 47304402200fadb0b7d19d0aca703a203ba612c3ca72fae86e863947ad7d6ea5cc628050a302204a1a3ee196b09e63ed6201af722d213b8bcdf3b2d935a6610450524bd72d1e8d012102936c15394948d03a7ba3d4a7e7c7523e14194b3ab808cfe5baed526e15bc0651 + sequence: 4294967295 + vout: + - value: 1.55690512 + 'n': 0 + scriptPubKey: + asm: >- + OP_DUP OP_HASH160 c8a6bc95dfec3fa60785b300278d5378c6d453a0 + OP_EQUALVERIFY OP_CHECKSIG + hex: 76a914c8a6bc95dfec3fa60785b300278d5378c6d453a088ac + reqSigs: 1 + type: pubkeyhash + addresses: + - 1KHwtS5mn7NMUm7Ls7Y1XwxLqMriLdaGbX + - value: 0.01498873 + 'n': 1 + scriptPubKey: + asm: 0 19dfb6e485d667649eb9027c577fc051dae71f0b + hex: 001419dfb6e485d667649eb9027c577fc051dae71f0b + reqSigs: 1 + type: witness_v0_keyhash + addresses: + - bc1qr80mdey96enkf84eqf79wl7q28dww8ctq2qu4e + hex: >- + 0100000001e9860bc1c053e376100a92db44dd0eb3d6241b851955ee2db514894ef3cf51c3020000006a47304402200fadb0b7d19d0aca703a203ba612c3ca72fae86e863947ad7d6ea5cc628050a302204a1a3ee196b09e63ed6201af722d213b8bcdf3b2d935a6610450524bd72d1e8d012102936c15394948d03a7ba3d4a7e7c7523e14194b3ab808cfe5baed526e15bc0651ffffffff0210a64709000000001976a914c8a6bc95dfec3fa60785b300278d5378c6d453a088acf9de16000000000016001419dfb6e485d667649eb9027c577fc051dae71f0b00000000 + - txid: d12f4c3c074767aafc1d2240b3424efe45e8b38f5841cee92c17549c91b87c4c + hash: 3d763c9cf31fbf490ef5d0788d7043539e1454dde00eebbede58b5ef93675521 + version: 1 + size: 373 + vsize: 208 + weight: 829 + locktime: 0 + vin: + - txid: 25c6586ad998154f31685b57a628fb392d85d9c8f315fb62c00ad63fb8cdc3bc + vout: 1 + scriptSig: + asm: 002028cdcdad4c4a07bb6ec5925f2196c4e293898127650b3044fbdb6bab317a7099 + hex: >- + 22002028cdcdad4c4a07bb6ec5925f2196c4e293898127650b3044fbdb6bab317a7099 + txinwitness: + - '' + - >- + 304402205797dac01c67c55dc766706c6cd8f5a26a30dc98bf05f2363acb9b9bcbbf317f022018c7e041a3a8b1f1b54a348fabaf6109a4f3d1a5f58f2ed55ac98ba372ede53201 + - >- + 3045022100b6a487645eb046b8dc028a7cfe758bbb03dea784655edeb443afe89cb61d14c70220655df45427eea9387e776b8ad7fe848fd9c215de8269f0348d381c4a0b12511701 + - >- + 522102ce06807bdaf64c3f40d3e4fe990910c82e8b8c3ac8df0c3cf373fa72823f958321039332e240be260cc87f6b1bae52aac5e37fcd61dd89849a8113f14d977e5f39dd52ae + sequence: 4294967295 + vout: + - value: 0.00425163 + 'n': 0 + scriptPubKey: + asm: >- + OP_DUP OP_HASH160 178412a75e907720a886591d008f10f9f3466f51 + OP_EQUALVERIFY OP_CHECKSIG + hex: 76a914178412a75e907720a886591d008f10f9f3466f5188ac + reqSigs: 1 + type: pubkeyhash + addresses: + - 139LkzkdvXoXEVbQyaXKFZNMFTRv26Juv3 + - value: 5.4261758 + 'n': 1 + scriptPubKey: + asm: OP_HASH160 ba695f1c0d90e1b0fbcc0f1f4623b815848a51f2 OP_EQUAL + hex: a914ba695f1c0d90e1b0fbcc0f1f4623b815848a51f287 + reqSigs: 1 + type: scripthash + addresses: + - 3JgfqZmwGFseH7hpkmrejyoryUkXaXriyE + hex: >- + 01000000000101bcc3cdb83fd60ac062fb15f3c8d9852d39fb28a6575b68314f1598d96a58c625010000002322002028cdcdad4c4a07bb6ec5925f2196c4e293898127650b3044fbdb6bab317a7099ffffffff02cb7c0600000000001976a914178412a75e907720a886591d008f10f9f3466f5188acecaf57200000000017a914ba695f1c0d90e1b0fbcc0f1f4623b815848a51f287040047304402205797dac01c67c55dc766706c6cd8f5a26a30dc98bf05f2363acb9b9bcbbf317f022018c7e041a3a8b1f1b54a348fabaf6109a4f3d1a5f58f2ed55ac98ba372ede53201483045022100b6a487645eb046b8dc028a7cfe758bbb03dea784655edeb443afe89cb61d14c70220655df45427eea9387e776b8ad7fe848fd9c215de8269f0348d381c4a0b1251170147522102ce06807bdaf64c3f40d3e4fe990910c82e8b8c3ac8df0c3cf373fa72823f958321039332e240be260cc87f6b1bae52aac5e37fcd61dd89849a8113f14d977e5f39dd52ae00000000 + - txid: e4fdefc4634dc473e8098632ac800b34f600b25579eaee4a31d05389ee7411b1 + hash: 811036883d0221655d8678f8705716398a5b4b814b5756e38b74a0a9210cce99 + version: 2 + size: 226 + vsize: 144 + weight: 574 + locktime: 0 + vin: + - txid: 7f1af3eaaa18972df7e4c5ffa6079f3649e00f2fc958259e74244bc890910525 + vout: 1 + scriptSig: + asm: '' + hex: '' + txinwitness: + - >- + 3045022100a06e32275e2398421c06b8a2e05716435dfd3d0338115c0121f17611f9cae15102200c7e7429ce64879c9a668d600185b8692aba933b3af2cb0d1bb645268452253b01 + - 02bdf3289ab542598c6cbb9d5fe8f07fe31da4495203061a11c9add18b57cf0c4b + sequence: 4294967295 + vout: + - value: 0.00148219 + 'n': 0 + scriptPubKey: + asm: 0 4e11f3feec543860df274eeab67012608ba93996 + hex: 00144e11f3feec543860df274eeab67012608ba93996 + reqSigs: 1 + type: witness_v0_keyhash + addresses: + - bc1qfcgl8lhv2suxphe8fm4tvuqjvz96jwvkhcksrf + - value: 0.00149835 + 'n': 1 + scriptPubKey: + asm: >- + OP_DUP OP_HASH160 ec03ec56b76c9398626fd14e17ea23c5e6ee0188 + OP_EQUALVERIFY OP_CHECKSIG + hex: 76a914ec03ec56b76c9398626fd14e17ea23c5e6ee018888ac + reqSigs: 1 + type: pubkeyhash + addresses: + - 1NWwArux9Dcof6Dm3vWXjQqMJ672pRgXEK + hex: >- + 0200000000010125059190c84b24749e2558c92f0fe049369f07a6ffc5e4f72d9718aaeaf31a7f0100000000ffffffff02fb420200000000001600144e11f3feec543860df274eeab67012608ba939964b490200000000001976a914ec03ec56b76c9398626fd14e17ea23c5e6ee018888ac02483045022100a06e32275e2398421c06b8a2e05716435dfd3d0338115c0121f17611f9cae15102200c7e7429ce64879c9a668d600185b8692aba933b3af2cb0d1bb645268452253b012102bdf3289ab542598c6cbb9d5fe8f07fe31da4495203061a11c9add18b57cf0c4b00000000 + - txid: 8d925bf3dff92af5db39bb866a75c610eddb9d7f290c4f8c7a71b449ae1cdaa9 + hash: 8d925bf3dff92af5db39bb866a75c610eddb9d7f290c4f8c7a71b449ae1cdaa9 + version: 1 + size: 223 + vsize: 223 + weight: 892 + locktime: 0 + vin: + - txid: 86bb6e699ec1e37250e2105e5a2a19a618b65f32437c02827314c736bd3e2788 + vout: 1 + scriptSig: + asm: >- + 3045022100f08866af42bd3b4cde4e0322aef9905e7e91b6f2fd6f74e07f98c4650c9449f502202419439695dfbaf00a43788de8ba6db011d19022f3c0f07dcbf7f712aa70cb42[ALL] + 03f9d3a6ee01d462dcd9e9833150169001afceb41c1076e08a2f435b59f8b1261a + hex: >- + 483045022100f08866af42bd3b4cde4e0322aef9905e7e91b6f2fd6f74e07f98c4650c9449f502202419439695dfbaf00a43788de8ba6db011d19022f3c0f07dcbf7f712aa70cb42012103f9d3a6ee01d462dcd9e9833150169001afceb41c1076e08a2f435b59f8b1261a + sequence: 4294967295 + vout: + - value: 0.02293671 + 'n': 0 + scriptPubKey: + asm: >- + OP_DUP OP_HASH160 4a58af826227a82b45bd48a69c0618e5f1de0d46 + OP_EQUALVERIFY OP_CHECKSIG + hex: 76a9144a58af826227a82b45bd48a69c0618e5f1de0d4688ac + reqSigs: 1 + type: pubkeyhash + addresses: + - 17n7FBK8DxyGq4ijx12NWeTa7GW2qDW6m4 + - value: 0.00115675 + 'n': 1 + scriptPubKey: + asm: 0 5a4f089fe01c25c865b23ee7eacd0ca7cf76e5e7 + hex: 00145a4f089fe01c25c865b23ee7eacd0ca7cf76e5e7 + reqSigs: 1 + type: witness_v0_keyhash + addresses: + - bc1qtf8s38lqrsjusedj8mn74ngv5l8hde08p8aa3u + hex: >- + 010000000188273ebd36c7147382027c43325fb618a6192a5a5e10e25072e3c19e696ebb86010000006b483045022100f08866af42bd3b4cde4e0322aef9905e7e91b6f2fd6f74e07f98c4650c9449f502202419439695dfbaf00a43788de8ba6db011d19022f3c0f07dcbf7f712aa70cb42012103f9d3a6ee01d462dcd9e9833150169001afceb41c1076e08a2f435b59f8b1261affffffff02a7ff2200000000001976a9144a58af826227a82b45bd48a69c0618e5f1de0d4688acdbc30100000000001600145a4f089fe01c25c865b23ee7eacd0ca7cf76e5e700000000 + - txid: c16f08cf1d0e53910ab1e297bf0d6b94141931f0cbf5e60f0f1fc55a09d6700b + hash: c16f08cf1d0e53910ab1e297bf0d6b94141931f0cbf5e60f0f1fc55a09d6700b + version: 2 + size: 223 + vsize: 223 + weight: 892 + locktime: 0 + vin: + - txid: c5e722eaa902a48f6ac0cea02f0b26e44629722e3eb568a2f43f268d3e0d41b1 + vout: 1 + scriptSig: + asm: >- + 304402204782f4a1a2ebc065ed1ff361784f2ea79242bf3f1c9720317754478041a734af02202bcd541b4e7b6b232a6b62a1b8679508b1e27e5e4f697b7f9a5d5fbf18a76387[ALL] + 02b1822ad675522904b61ac135b8a9d36e9b28a1c13b6e54e7e281e746d4d0bb73 + hex: >- + 47304402204782f4a1a2ebc065ed1ff361784f2ea79242bf3f1c9720317754478041a734af02202bcd541b4e7b6b232a6b62a1b8679508b1e27e5e4f697b7f9a5d5fbf18a76387012102b1822ad675522904b61ac135b8a9d36e9b28a1c13b6e54e7e281e746d4d0bb73 + sequence: 4294967295 + vout: + - value: 0.03004015 + 'n': 0 + scriptPubKey: + asm: OP_HASH160 0e9259a0faf3c56342caeeec43d61e2184a1144a OP_EQUAL + hex: a9140e9259a0faf3c56342caeeec43d61e2184a1144a87 + reqSigs: 1 + type: scripthash + addresses: + - 3324hp8mgcAN9xYU1NeJsJDPXJNixgSkB2 + - value: 0.20598408 + 'n': 1 + scriptPubKey: + asm: >- + OP_DUP OP_HASH160 8b41c041d8dadc41d3efd8b0d430ac80274377ec + OP_EQUALVERIFY OP_CHECKSIG + hex: 76a9148b41c041d8dadc41d3efd8b0d430ac80274377ec88ac + reqSigs: 1 + type: pubkeyhash + addresses: + - 1DhKh8DF1MrEaPo9eC67quEQzWQuJGwEbp + hex: >- + 0200000001b1410d3e8d263ff4a268b53e2e722946e4260b2fa0cec06a8fa402a9ea22e7c5010000006a47304402204782f4a1a2ebc065ed1ff361784f2ea79242bf3f1c9720317754478041a734af02202bcd541b4e7b6b232a6b62a1b8679508b1e27e5e4f697b7f9a5d5fbf18a76387012102b1822ad675522904b61ac135b8a9d36e9b28a1c13b6e54e7e281e746d4d0bb73ffffffff026fd62d000000000017a9140e9259a0faf3c56342caeeec43d61e2184a1144a87884e3a01000000001976a9148b41c041d8dadc41d3efd8b0d430ac80274377ec88ac00000000 + - txid: 2f8a80a59a5336fd31d9aa789b553fa4874a1cfff9216870048f4b000be9014f + hash: e479d92908daa39e8acc8faee5adfe45a535c5f5c72b40c254330ac6551f62e7 + version: 1 + size: 785 + vsize: 541 + weight: 2162 + locktime: 0 + vin: + - txid: 5fdbed41eb0861c55d653d28d29b1f27b7aa4d105e269ebb8a51053ce5e3eb06 + vout: 0 + scriptSig: + asm: >- + 3045022100cb23733b6e14b9ef5381db429cc02bd7dcecb2ec620981f17e3cf9d007852d240220090f16b37f50daccd81cbd4b1a154263f9100ecdb76a7ead967f26d280ae9c1f[ALL] + 03da3e84d6d636f2022282db92433773f703d2fb738fe59a5d77da5adc3e2c7e1d + hex: >- + 483045022100cb23733b6e14b9ef5381db429cc02bd7dcecb2ec620981f17e3cf9d007852d240220090f16b37f50daccd81cbd4b1a154263f9100ecdb76a7ead967f26d280ae9c1f012103da3e84d6d636f2022282db92433773f703d2fb738fe59a5d77da5adc3e2c7e1d + sequence: 4294967295 + - txid: 257efd64791a885e8593b61f7b4389fa3ea69b071e06e82b6757f6f8c975c173 + vout: 0 + scriptSig: + asm: >- + 304402204d6c6a89b44588f1fc2d77f01217eafa122d4c5487e62026a7a5d56f1d1ca119022002239b5f2cccf82f2bf0b7c8621020bc499757dcd14b126906503599c425a3a3[ALL] + 0387114296e1c4edadc0c47482b0961e8c9ca37ea256d097c2b49583f19ac59856 + hex: >- + 47304402204d6c6a89b44588f1fc2d77f01217eafa122d4c5487e62026a7a5d56f1d1ca119022002239b5f2cccf82f2bf0b7c8621020bc499757dcd14b126906503599c425a3a301210387114296e1c4edadc0c47482b0961e8c9ca37ea256d097c2b49583f19ac59856 + sequence: 4294967295 + - txid: 7b5c1238aa9d6be5c6c673d233cbe41b320cb39ac91c031ca9c85feddf0870b1 + vout: 0 + scriptSig: + asm: '' + hex: '' + txinwitness: + - >- + 3044022041bf6e490c22f9b2e817322257e269d712896091414ea5444098815ec8537fdd0220280101a6b811d57b79258b36f69bf4b16bfec35b96d75ce80f83de872884678601 + - 0363e40bd07d4ef8b06aedc340b7a0ad588d5bee7234b74a69313872cba2d0dc29 + sequence: 4294967295 + - txid: 6b8988d701d13b97775b0f0bcdc33ecd833fe53a83ec6df4225d3822e8c748b4 + vout: 0 + scriptSig: + asm: '' + hex: '' + txinwitness: + - >- + 3045022100933da4eed06a472c7a8911b9885ed1e25675c7f6dbfdcddc8a2be437184dade502202a40b5b2a5f6a647d01b8f9177f89132947b39e0ec7f4d60bd1ad1ec504d22f301 + - 03093f9569270b106f0b41cf96e56363ef093b90d1c97da552322f7e67bac7f151 + sequence: 4294967295 + - txid: 6a9f50060d2a0fc44c0a4701b0f6e72a758545b474d9582c9f669b2d91e65331 + vout: 0 + scriptSig: + asm: '' + hex: '' + txinwitness: + - >- + 30440220097003a8faeba34e9118b16920390ab2748970ee14c8ba484e691173330eea5f02201ca72e92ebf06541d91499b81b8f4f5a322997f610e06c16cf0eecf04c621cf901 + - 02f8857de858c14dc3836b026ab88b6038f5716f923275d40fe7207e43c687bc60 + sequence: 4294967295 + vout: + - value: 0.0796458 + 'n': 0 + scriptPubKey: + asm: 0 36552a1c649baccfee51d6bffb1951e3685ed692 + hex: 001436552a1c649baccfee51d6bffb1951e3685ed692 + reqSigs: 1 + type: witness_v0_keyhash + addresses: + - bc1qxe2j58rynwkvlmj366llkx23ud59a45jpe5q9a + hex: >- + 0100000000010506ebe3e53c05518abb9e265e104daab7271f9bd2283d655dc56108eb41eddb5f000000006b483045022100cb23733b6e14b9ef5381db429cc02bd7dcecb2ec620981f17e3cf9d007852d240220090f16b37f50daccd81cbd4b1a154263f9100ecdb76a7ead967f26d280ae9c1f012103da3e84d6d636f2022282db92433773f703d2fb738fe59a5d77da5adc3e2c7e1dffffffff73c175c9f8f657672be8061e079ba63efa89437b1fb693855e881a7964fd7e25000000006a47304402204d6c6a89b44588f1fc2d77f01217eafa122d4c5487e62026a7a5d56f1d1ca119022002239b5f2cccf82f2bf0b7c8621020bc499757dcd14b126906503599c425a3a301210387114296e1c4edadc0c47482b0961e8c9ca37ea256d097c2b49583f19ac59856ffffffffb17008dfed5fc8a91c031cc99ab30c321be4cb33d273c6c6e56b9daa38125c7b0000000000ffffffffb448c7e822385d22f46dec833ae53f83cd3ec3cd0b0f5b77973bd101d788896b0000000000ffffffff3153e6912d9b669f2c58d974b44585752ae7f6b001470a4cc40f2a0d06509f6a0000000000ffffffff01a48779000000000016001436552a1c649baccfee51d6bffb1951e3685ed692000002473044022041bf6e490c22f9b2e817322257e269d712896091414ea5444098815ec8537fdd0220280101a6b811d57b79258b36f69bf4b16bfec35b96d75ce80f83de872884678601210363e40bd07d4ef8b06aedc340b7a0ad588d5bee7234b74a69313872cba2d0dc2902483045022100933da4eed06a472c7a8911b9885ed1e25675c7f6dbfdcddc8a2be437184dade502202a40b5b2a5f6a647d01b8f9177f89132947b39e0ec7f4d60bd1ad1ec504d22f3012103093f9569270b106f0b41cf96e56363ef093b90d1c97da552322f7e67bac7f151024730440220097003a8faeba34e9118b16920390ab2748970ee14c8ba484e691173330eea5f02201ca72e92ebf06541d91499b81b8f4f5a322997f610e06c16cf0eecf04c621cf9012102f8857de858c14dc3836b026ab88b6038f5716f923275d40fe7207e43c687bc6000000000 + - txid: edd1110933f0c45d65fd67daf816b5ccb69eee41cc4e6cd3a2132815bc762ac5 + hash: edd1110933f0c45d65fd67daf816b5ccb69eee41cc4e6cd3a2132815bc762ac5 + version: 1 + size: 224 + vsize: 224 + weight: 896 + locktime: 0 + vin: + - txid: 7cc01e7cf54d8789d1a596f7f8dd72a2bfe9ff88ad948091c5df2be6d9891c98 + vout: 0 + scriptSig: + asm: >- + 3045022100ba0fd24606b8c9480d28478b40486dbc0c830ac11ad6f56cdaaf3273026f02ab02202c1e0673a2dd7be785425c83bed148890db59d51377eb124e4beba068b239c8e[ALL] + 048454d039fb7bde4e32c0fccd96dac9a7de33879666ee3ed2e9c88971ce4ed9e37b2828d634789b222c053f6547e6ecdf4869201e74f72267f48f297b7b644339 + hex: >- + 483045022100ba0fd24606b8c9480d28478b40486dbc0c830ac11ad6f56cdaaf3273026f02ab02202c1e0673a2dd7be785425c83bed148890db59d51377eb124e4beba068b239c8e0141048454d039fb7bde4e32c0fccd96dac9a7de33879666ee3ed2e9c88971ce4ed9e37b2828d634789b222c053f6547e6ecdf4869201e74f72267f48f297b7b644339 + sequence: 4294967295 + vout: + - value: 0.00519844 + 'n': 0 + scriptPubKey: + asm: >- + OP_DUP OP_HASH160 c248b989aae8d90a6242da04f19fa912dc6e8f10 + OP_EQUALVERIFY OP_CHECKSIG + hex: 76a914c248b989aae8d90a6242da04f19fa912dc6e8f1088ac + reqSigs: 1 + type: pubkeyhash + addresses: + - 1JiHDDkPhvwBrdaiYd2CqVLxsPdypEKPa9 + hex: >- + 0100000001981c89d9e62bdfc5918094ad88ffe9bfa272ddf8f796a5d189874df57c1ec07c000000008b483045022100ba0fd24606b8c9480d28478b40486dbc0c830ac11ad6f56cdaaf3273026f02ab02202c1e0673a2dd7be785425c83bed148890db59d51377eb124e4beba068b239c8e0141048454d039fb7bde4e32c0fccd96dac9a7de33879666ee3ed2e9c88971ce4ed9e37b2828d634789b222c053f6547e6ecdf4869201e74f72267f48f297b7b644339ffffffff01a4ee0700000000001976a914c248b989aae8d90a6242da04f19fa912dc6e8f1088ac00000000 + - txid: 6bcc04db47b81fd8c2c317a5ddd4236afbe0e2c9f96065f333976202c46163c4 + hash: dcc781655a9246f83789fc40849861684f863577bbae8b1ae1824b9dfccd1076 + version: 2 + size: 518 + vsize: 435 + weight: 1739 + locktime: 0 + vin: + - txid: 2a9046ac0bab75714be9c1000a2eb7849a26d6532e89fbff064184de488afd4a + vout: 12 + scriptSig: + asm: >- + 304402204378a0385b713cb38224082a571a195f44680607480be725a7caa7c2ae74883e022002f72e9c716fe958f0346270c7225fba8ed5c6e5e5e4fccd9d0b18c5aed34a71[ALL] + 02a3576bc2466fb6233dadf3df9ce7c92f93965b56b2b1de17ecd933de21eb16b0 + hex: >- + 47304402204378a0385b713cb38224082a571a195f44680607480be725a7caa7c2ae74883e022002f72e9c716fe958f0346270c7225fba8ed5c6e5e5e4fccd9d0b18c5aed34a71012102a3576bc2466fb6233dadf3df9ce7c92f93965b56b2b1de17ecd933de21eb16b0 + sequence: 4294967295 + - txid: 49cb5ef6a4d9da7cbbb146fbeebf084b16b4537fc2662a597db66915b6f0e1de + vout: 0 + scriptSig: + asm: >- + 304402200cb20f9b6e76cc4c37dc4ce8899e556726dd475e5115e381b8a980ad0a95eb58022078e5af79d0bd41ce07568eba335123dd17c1f1aae8d0c87377368ad4cb7e0d09[ALL] + 02a3576bc2466fb6233dadf3df9ce7c92f93965b56b2b1de17ecd933de21eb16b0 + hex: >- + 47304402200cb20f9b6e76cc4c37dc4ce8899e556726dd475e5115e381b8a980ad0a95eb58022078e5af79d0bd41ce07568eba335123dd17c1f1aae8d0c87377368ad4cb7e0d09012102a3576bc2466fb6233dadf3df9ce7c92f93965b56b2b1de17ecd933de21eb16b0 + sequence: 4294967295 + - txid: 55547dc947bdf347d230d26bf0fe3c52a32f6dc3cf950ed19d6bfa201ee5a8ad + vout: 1 + scriptSig: + asm: '' + hex: '' + txinwitness: + - >- + 30440220673f1e40d5977a114633e8822c520bd0b0d96a83e0b0378a26de89ede6c15d1102201a0989d550e84cfa342e5bd8ed28b364e0c4702c1f271245bb3277b6ae204e5d01 + - 02b648eb3b32f72dc612c0412db37bba2ac30c44014e7a7581f52ce54e4d67b9d8 + sequence: 4294967295 + vout: + - value: 0.03539112 + 'n': 0 + scriptPubKey: + asm: 0 de83d2189cedab4d984ab78488f00dfdf5e32870 + hex: 0014de83d2189cedab4d984ab78488f00dfdf5e32870 + reqSigs: 1 + type: witness_v0_keyhash + addresses: + - bc1qm6payxyuak45mxz2k7zg3uqdlh67x2rsux9lvp + - value: 0.00960533 + 'n': 1 + scriptPubKey: + asm: 0 ea01e04aaafa8255b47ede6648e7a0c111431bca + hex: 0014ea01e04aaafa8255b47ede6648e7a0c111431bca + reqSigs: 1 + type: witness_v0_keyhash + addresses: + - bc1qagq7qj42l2p9tdr7meny3eaqcyg5xx722cvsgg + hex: >- + 020000000001034afd8a48de844106fffb892e53d6269a84b72e0a00c1e94b7175ab0bac46902a0c0000006a47304402204378a0385b713cb38224082a571a195f44680607480be725a7caa7c2ae74883e022002f72e9c716fe958f0346270c7225fba8ed5c6e5e5e4fccd9d0b18c5aed34a71012102a3576bc2466fb6233dadf3df9ce7c92f93965b56b2b1de17ecd933de21eb16b0ffffffffdee1f0b61569b67d592a66c27f53b4164b08bfeefb46b1bb7cdad9a4f65ecb49000000006a47304402200cb20f9b6e76cc4c37dc4ce8899e556726dd475e5115e381b8a980ad0a95eb58022078e5af79d0bd41ce07568eba335123dd17c1f1aae8d0c87377368ad4cb7e0d09012102a3576bc2466fb6233dadf3df9ce7c92f93965b56b2b1de17ecd933de21eb16b0ffffffffada8e51e20fa6b9dd10e95cfc36d2fa3523cfef06bd230d247f3bd47c97d54550100000000ffffffff02a800360000000000160014de83d2189cedab4d984ab78488f00dfdf5e3287015a80e0000000000160014ea01e04aaafa8255b47ede6648e7a0c111431bca0000024730440220673f1e40d5977a114633e8822c520bd0b0d96a83e0b0378a26de89ede6c15d1102201a0989d550e84cfa342e5bd8ed28b364e0c4702c1f271245bb3277b6ae204e5d012102b648eb3b32f72dc612c0412db37bba2ac30c44014e7a7581f52ce54e4d67b9d800000000 + - txid: 53d90a6c9c6368dee7e1a3280c10db924ef3f92648465fdd0c40614f88e8c2c8 + hash: 53d90a6c9c6368dee7e1a3280c10db924ef3f92648465fdd0c40614f88e8c2c8 + version: 2 + size: 372 + vsize: 372 + weight: 1488 + locktime: 0 + vin: + - txid: 76af1408e8ba6bd2d00869adb0bca40e5d81da988fd6b7d4a184909709758670 + vout: 0 + scriptSig: + asm: >- + 3044022048966d6c364ec2cbac56965426a62ad8ff0055fbdaef9114da883b9f99baeb300220484dc01e8f5d71d33b8e6d09c5c5a4051a8ca0613e1dd41318e9a1eec955a6ae[ALL] + 02537169a50154c653f1f9799cfda9ea4440108225370cb3db520a0e260ef4ef03 + hex: >- + 473044022048966d6c364ec2cbac56965426a62ad8ff0055fbdaef9114da883b9f99baeb300220484dc01e8f5d71d33b8e6d09c5c5a4051a8ca0613e1dd41318e9a1eec955a6ae012102537169a50154c653f1f9799cfda9ea4440108225370cb3db520a0e260ef4ef03 + sequence: 4294967295 + - txid: 79e7c086d4544a92e87ddec7f78b981c86d3a0c1c0422333ac129024c95fd8b4 + vout: 0 + scriptSig: + asm: >- + 3044022001f390a3895940a9c777c0190c0f54716c2bfbd6a278458b7bbbab1e9a974b1a022001d553243f0f025ed609fa2519015682b8c4fe8167cfc5eb2ff34e107ea38708[ALL] + 02537169a50154c653f1f9799cfda9ea4440108225370cb3db520a0e260ef4ef03 + hex: >- + 473044022001f390a3895940a9c777c0190c0f54716c2bfbd6a278458b7bbbab1e9a974b1a022001d553243f0f025ed609fa2519015682b8c4fe8167cfc5eb2ff34e107ea38708012102537169a50154c653f1f9799cfda9ea4440108225370cb3db520a0e260ef4ef03 + sequence: 4294967295 + vout: + - value: 0.0261158 + 'n': 0 + scriptPubKey: + asm: >- + OP_DUP OP_HASH160 8bfc0653d121bf6367c9b78f0f12c3a6880bf166 + OP_EQUALVERIFY OP_CHECKSIG + hex: 76a9148bfc0653d121bf6367c9b78f0f12c3a6880bf16688ac + reqSigs: 1 + type: pubkeyhash + addresses: + - 1DmAqedH6fKhjH4pMg6UMrhaiZW9FyGnYf + - value: 0.031484 + 'n': 1 + scriptPubKey: + asm: >- + OP_DUP OP_HASH160 205826a3fb33a0fcd8c8e177247b48877508260f + OP_EQUALVERIFY OP_CHECKSIG + hex: 76a914205826a3fb33a0fcd8c8e177247b48877508260f88ac + reqSigs: 1 + type: pubkeyhash + addresses: + - 13x2DySy58j9FJxas7EsgmQb8M1MGXLYxr + hex: >- + 020000000270867509979084a1d4b7d68f98da815d0ea4bcb0ad6908d0d26bbae80814af76000000006a473044022048966d6c364ec2cbac56965426a62ad8ff0055fbdaef9114da883b9f99baeb300220484dc01e8f5d71d33b8e6d09c5c5a4051a8ca0613e1dd41318e9a1eec955a6ae012102537169a50154c653f1f9799cfda9ea4440108225370cb3db520a0e260ef4ef03ffffffffb4d85fc9249012ac332342c0c1a0d3861c988bf7c7de7de8924a54d486c0e779000000006a473044022001f390a3895940a9c777c0190c0f54716c2bfbd6a278458b7bbbab1e9a974b1a022001d553243f0f025ed609fa2519015682b8c4fe8167cfc5eb2ff34e107ea38708012102537169a50154c653f1f9799cfda9ea4440108225370cb3db520a0e260ef4ef03ffffffff027cd92700000000001976a9148bfc0653d121bf6367c9b78f0f12c3a6880bf16688ac700a3000000000001976a914205826a3fb33a0fcd8c8e177247b48877508260f88ac00000000 + - txid: 4d944e129c6356d69a59196a845b7bcbbeb7898aae9a9acd817293ae982ad381 + hash: 4cc9636627aa40d2c0decec515116705e781cc8763dda0524cc2d4dd60432082 + version: 2 + size: 372 + vsize: 209 + weight: 834 + locktime: 0 + vin: + - txid: 876f687396eaa1dc1f22afee63294b5750a1190e3d012ea30e8ef8d1bb4ca3e6 + vout: 1 + scriptSig: + asm: '' + hex: '' + txinwitness: + - >- + 3045022100c99a034876bab21f203f6a8c0f7de3c43ab2aea76e8a2747c39dc9440eb42882022007a636ac3e8f822c9843e8ab2a03792657dfb01703009b016cd778ecd50bf95901 + - 022ee959f516a8d466b32e0a856411a389ea452c8a3b82b12f2f648aba82e00562 + sequence: 4294967295 + - txid: 07e3544edd4bd669c7c3ca1e47a096421b762a5f85a3dce3d38e63eb79b6a79c + vout: 1 + scriptSig: + asm: '' + hex: '' + txinwitness: + - >- + 30450221009b718162daff3ee7e235371b022d23d0592ab019671bbc7d3cf172a72a8479860220745e9050835eff30c3d7d70cddc84632819d110a3a6a245abd42b9bae23bba1801 + - 02cc4a45037362de7a630870382f1fee915a1dfcaa0d1738dc9b503eb7726504b4 + sequence: 4294967295 + vout: + - value: 0.01348519 + 'n': 0 + scriptPubKey: + asm: 0 7eef9a2c606f75f7ee5995b6b5a65ee512e08451 + hex: 00147eef9a2c606f75f7ee5995b6b5a65ee512e08451 + reqSigs: 1 + type: witness_v0_keyhash + addresses: + - bc1q0mhe5trqda6l0mjejkmttfj7u5fwppz3lfa98e + - value: 0.00800995 + 'n': 1 + scriptPubKey: + asm: 0 59f627e531193db7f3a525ae32df9eb453703284 + hex: 001459f627e531193db7f3a525ae32df9eb453703284 + reqSigs: 1 + type: witness_v0_keyhash + addresses: + - bc1qt8mz0ef3ry7m0ua9ykhr9hu7k3fhqv5yp7ty49 + hex: >- + 02000000000102e6a34cbbd1f88e0ea32e013d0e19a150574b2963eeaf221fdca1ea9673686f870100000000ffffffff9ca7b679eb638ed3e3dca3855f2a761b4296a0471ecac3c769d64bdd4e54e3070100000000ffffffff02a7931400000000001600147eef9a2c606f75f7ee5995b6b5a65ee512e08451e3380c000000000016001459f627e531193db7f3a525ae32df9eb45370328402483045022100c99a034876bab21f203f6a8c0f7de3c43ab2aea76e8a2747c39dc9440eb42882022007a636ac3e8f822c9843e8ab2a03792657dfb01703009b016cd778ecd50bf9590121022ee959f516a8d466b32e0a856411a389ea452c8a3b82b12f2f648aba82e00562024830450221009b718162daff3ee7e235371b022d23d0592ab019671bbc7d3cf172a72a8479860220745e9050835eff30c3d7d70cddc84632819d110a3a6a245abd42b9bae23bba18012102cc4a45037362de7a630870382f1fee915a1dfcaa0d1738dc9b503eb7726504b400000000 + - txid: 62a7743d513269900956a793db563fa0b7e474924a0aefbf084af52dd319045d + hash: b94a8101bfdcdc13f7eb6312720b21e6840934205edc627a4ac66766617fb572 + version: 2 + size: 223 + vsize: 142 + weight: 565 + locktime: 0 + vin: + - txid: bff39ede27c5991021c0a6f325acb773cb658660e11148523e1f6441e8adca52 + vout: 1 + scriptSig: + asm: '' + hex: '' + txinwitness: + - >- + 3044022020c878f15145a3c407126a712862a19e8d0c6066ae26edb100dd8f2ac410bdfe022034d547cc3e9fc059b4c4ca52cca2a6a4c44c34d563abdda59738dbdae08950e601 + - 02b86fbb247c7a6ae45aac84f5633b59ba2a09a3dd09d0fe239d36e20267104964 + sequence: 4294967295 + vout: + - value: 0.00059934 + 'n': 0 + scriptPubKey: + asm: OP_HASH160 69ab330f75fd4cc065a2151a3fc7676fefb8a75b OP_EQUAL + hex: a91469ab330f75fd4cc065a2151a3fc7676fefb8a75b87 + reqSigs: 1 + type: scripthash + addresses: + - 3BKjxqF6iZGXWkABFCpUk8ke6V2JLQ6QSs + - value: 0.00293909 + 'n': 1 + scriptPubKey: + asm: 0 c4485c0c4bf12c3eba18a86c35611662f9216d63 + hex: 0014c4485c0c4bf12c3eba18a86c35611662f9216d63 + reqSigs: 1 + type: witness_v0_keyhash + addresses: + - bc1qc3y9crzt7ykrawsc4pkr2cgkvtujzmtraqdzyz + hex: >- + 0200000000010152caade841641f3e524811e1608665cb73b7ac25f3a6c0211099c527de9ef3bf0100000000ffffffff021eea00000000000017a91469ab330f75fd4cc065a2151a3fc7676fefb8a75b87157c040000000000160014c4485c0c4bf12c3eba18a86c35611662f9216d6302473044022020c878f15145a3c407126a712862a19e8d0c6066ae26edb100dd8f2ac410bdfe022034d547cc3e9fc059b4c4ca52cca2a6a4c44c34d563abdda59738dbdae08950e6012102b86fbb247c7a6ae45aac84f5633b59ba2a09a3dd09d0fe239d36e2026710496400000000 + - txid: b0ac29dcca602bd28024c918942ba332e506ed132c6a7a41417d9b7f480731fb + hash: 56c9fe5c35ea29ce87e954dd9a826c4e4f6a8ec06b165aa53bfcf217a80cb26c + version: 1 + size: 910 + vsize: 505 + weight: 2020 + locktime: 0 + vin: + - txid: 0cfae00dd82e83c046809afe0996e109e4c86a3e974148e85c8941e0e98f40d8 + vout: 16 + scriptSig: + asm: '' + hex: '' + txinwitness: + - >- + 304402201147a76e63ed59be3cf36ca41f0a6820a54b36b05ac7fa0754bc73f584f80fce022073bc8f2af98b17abdf25add10bb518201b99398940f86a769760c011f1e4d5c301 + - 028660ea442a740bc31c79c1b4edbde91c0ccda97fe43a8f32c4116daacbce632d + sequence: 4294967295 + - txid: 68e6c3131adebc689902d35f7f7a1ec76c5f8860c4bbfe7db59493f380e43c82 + vout: 1 + scriptSig: + asm: '' + hex: '' + txinwitness: + - >- + 3045022100e3a3598e60387c3494fbf2e554ccd66d7535ba3f5f611c2cf94e5d76d318e77102207987a0d22c313bf95eade88e076d4a4a9d180aeb160917024426ad250285507701 + - 02899f0e9705052e458e67339e9812535f648fdc55242fdd43fa9474387745f448 + sequence: 4294967295 + - txid: 8f4841c5e1de8d72cda38c4af1567301e226773618b964150890cfef29456c33 + vout: 0 + scriptSig: + asm: '' + hex: '' + txinwitness: + - >- + 3045022100ae8235cfa4affd0a3c27b9ea2aef31eb6155ad8362b6ec2708299a6e4f3ea60202203d1f2d2cc993be5a199df912982d72263a632c18bfc69d00a09406acb1ba674701 + - 023f578ac20dfb94d1ccb0d067f4e2f610006ac2ceeaec39f74fcaa0cb515cef46 + sequence: 4294967295 + - txid: a8e91599535a157b6eb8528635b43145752eddfa1206e241a62105ea9105b463 + vout: 0 + scriptSig: + asm: '' + hex: '' + txinwitness: + - >- + 3044022064a248d9b84e327eaae7dfb7394281807d813b52f955384684842f523462024c0220544fe4345f8ae496ae26cff6eaaac607fa6495156460ec4820f41fafe6d08f8701 + - 03b61a1d01ca68ad214724ee0df5d96b201faf16dc3abc02346d51c6c097211cab + sequence: 4294967295 + - txid: d4365c7c2b04a6ea70e67d0ee5dc935d90fc0d0c3422564b9059c9b7e599f6af + vout: 59 + scriptSig: + asm: '' + hex: '' + txinwitness: + - >- + 3045022100a40cb59269085e50bd95c4d83a814cdaa9d0923dfbbbebfa3ddace33e567a9ab02205aa027d73e5896b125ce43943a45823710f43402f0a998cee9ca3486945197c201 + - 037175a85efd47494b868919a5cd31e909fd5b3be180c1117be5ebe7b2afabbcaa + sequence: 4294967295 + vout: + - value: 0.01 + 'n': 0 + scriptPubKey: + asm: 0 2ff099afd4dbc6506ad488760a39574d521e51b8 + hex: 00142ff099afd4dbc6506ad488760a39574d521e51b8 + reqSigs: 1 + type: witness_v0_keyhash + addresses: + - bc1q9lcfnt75m0r9q6k53pmq5w2hf4fpu5dc3ttakw + - value: 0.01 + 'n': 1 + scriptPubKey: + asm: 0 ce6fcea06b82087b16a78a8372b3c6b3a961e764 + hex: 0014ce6fcea06b82087b16a78a8372b3c6b3a961e764 + reqSigs: 1 + type: witness_v0_keyhash + addresses: + - bc1qeehuagrtsgy8k94832ph9v7xkw5kremymp57zu + - value: 0.01 + 'n': 2 + scriptPubKey: + asm: 0 db151b79d83e1864c0c3d5541d45ef9f2c4d2193 + hex: 0014db151b79d83e1864c0c3d5541d45ef9f2c4d2193 + reqSigs: 1 + type: witness_v0_keyhash + addresses: + - bc1qmv23k7wc8cvxfsxr642p6300nuky6gvncvm8tr + - value: 0.01 + 'n': 3 + scriptPubKey: + asm: 0 f05fa715a390cea1736a7b2a0259c23c3d77c4c0 + hex: 0014f05fa715a390cea1736a7b2a0259c23c3d77c4c0 + reqSigs: 1 + type: witness_v0_keyhash + addresses: + - bc1q7p06w9drjr82zum20v4qykwz8s7h03xqux9qvq + - value: 0.01 + 'n': 4 + scriptPubKey: + asm: 0 f18aed18bce9d56deb56115cd351fbe9990a7a5a + hex: 0014f18aed18bce9d56deb56115cd351fbe9990a7a5a + reqSigs: 1 + type: witness_v0_keyhash + addresses: + - bc1q7x9w6x9ua82km66kz9wdx50maxvs57j6u45cgf + hex: >- + 01000000000105d8408fe9e041895ce84841973e6ac8e409e19609fe9a8046c0832ed80de0fa0c1000000000ffffffff823ce480f39394b57dfebbc460885f6cc71e7a7f5fd3029968bcde1a13c3e6680100000000ffffffff336c4529efcf90081564b918367726e2017356f14a8ca3cd728ddee1c541488f0000000000ffffffff63b40591ea0521a641e20612fadd2e754531b4358652b86e7b155a539915e9a80000000000ffffffffaff699e5b7c959904b5622340c0dfc905d93dce50e7de670eaa6042b7c5c36d43b00000000ffffffff0540420f00000000001600142ff099afd4dbc6506ad488760a39574d521e51b840420f0000000000160014ce6fcea06b82087b16a78a8372b3c6b3a961e76440420f0000000000160014db151b79d83e1864c0c3d5541d45ef9f2c4d219340420f0000000000160014f05fa715a390cea1736a7b2a0259c23c3d77c4c040420f0000000000160014f18aed18bce9d56deb56115cd351fbe9990a7a5a0247304402201147a76e63ed59be3cf36ca41f0a6820a54b36b05ac7fa0754bc73f584f80fce022073bc8f2af98b17abdf25add10bb518201b99398940f86a769760c011f1e4d5c30121028660ea442a740bc31c79c1b4edbde91c0ccda97fe43a8f32c4116daacbce632d02483045022100e3a3598e60387c3494fbf2e554ccd66d7535ba3f5f611c2cf94e5d76d318e77102207987a0d22c313bf95eade88e076d4a4a9d180aeb160917024426ad2502855077012102899f0e9705052e458e67339e9812535f648fdc55242fdd43fa9474387745f44802483045022100ae8235cfa4affd0a3c27b9ea2aef31eb6155ad8362b6ec2708299a6e4f3ea60202203d1f2d2cc993be5a199df912982d72263a632c18bfc69d00a09406acb1ba67470121023f578ac20dfb94d1ccb0d067f4e2f610006ac2ceeaec39f74fcaa0cb515cef4602473044022064a248d9b84e327eaae7dfb7394281807d813b52f955384684842f523462024c0220544fe4345f8ae496ae26cff6eaaac607fa6495156460ec4820f41fafe6d08f87012103b61a1d01ca68ad214724ee0df5d96b201faf16dc3abc02346d51c6c097211cab02483045022100a40cb59269085e50bd95c4d83a814cdaa9d0923dfbbbebfa3ddace33e567a9ab02205aa027d73e5896b125ce43943a45823710f43402f0a998cee9ca3486945197c20121037175a85efd47494b868919a5cd31e909fd5b3be180c1117be5ebe7b2afabbcaa00000000 + time: 1625711473 + mediantime: 1625709499 + nonce: 3766546692 + bits: 171398ce + difficulty: 14363025673659.96 + chainwork: 00000000000000000000000000000000000000001f524d61662558d4d5cc1f48 + nTx: 32 + previousblockhash: 000000000000000000051d08578c5869136ba1fedc857c79c244846d3f988cf1 + nextblockhash: 00000000000000000013825a2e7d5da4f3f003ed6a7c05e0bcff3328a0366927 + + + + + + btc: getblockheader: @@ -322,51 +2318,97 @@ btc: nextblockhash: "0000000000001c0533ea776756cb6fdedbd952d3ab8bc71de3cd3f8a44cbaf85" getblock: - config: - proof: 'none' - input: - - "00000000000000001e8d6829a8a21adc5d38d0a473b144b6765798e61f98bd1d" - expected_output: - options: - bytes: "0100000081cd02ab7e569e8bcd9317e2fe99f2de44d49ab2b8851ba4a308000000000000e320b6c2fffc8d750423db8b1eb942ae710e951ed797f7affc8892b0f1fc122bc7f5d74df2b9441a42a146950401000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0804f2b9441a022a01ffffffff014034152a01000000434104d879d5ef8b70cf0a33925101b64429ad7eb370da8ad0b05c9cd60922c363a1eada85bcc2843b7378e226735048786c790b30b28438d22acfade24ef047b5f865ac000000000100000001ad6279669bcc8e3003267d97c9e364a9835ea7a5b53871d057783ef96f468d73000000008c4930460221009805aa00cb6f80ca984584d4ca40f637fc948e3dbe159ea5c4eb6941bf4eb763022100e1cc0852d3f6eb87839edca1f90169088ed3502d8cde2f495840acac69eefc9801410486477e6a23cb25c9a99f0c467c6fc86197e718ebfd41d1aef7cc3cbd75197c1f1aaba985b22b366a0729ccb8aa38277809d6d218cf4077ac9f29a953b5435222ffffffff0280f0fa02000000001976a9146f31097e564b9d54ebad662d5c4b5621c18ff52388ac007ddaac000000001976a9147228033b48b380900501c39c61da4ab453ca88e888ac0000000001000000035a19f341c42071f9cec7df37c4853c95d6aecc95e3bf19e3181d30d99552b8c9000000008a473044022025bca5dc0fe42aca5f07c9b3fe1b3f72113ffbc3522f8d3ebb2457f5bdf8f9b2022030ff687c00a63e810b21e447d3a57b2749ebea553cab763eb9b99e1b9839653b014104469f7eb54b90d90106b1a5412b41a23516028e81ad35e0418a4460707ae39a4bf0101b632260fb08979aba0ceea576b5400c7cf30b539b055ec4c0b96ab00984ffffffff5b72d3f4b6b72b3511bddd9994f28a91cc03212f200f71b91df13e711d58c1da000000008c493046022100fbef2589b7c52a3be0fd8dd3624445da9c8930f0e51f6a33d76dc0ca0304473d0221009ec433ca6a9f16184db46468ff39cafaa9643021e0c66a1de1e6f9a612092790014104b27f4de096ac6431eec4b807a0d3db3e9f9be48faab692d5559624acb1faf4334dd440ebf32a81506b7c49d8cf40e4b3f5c6b6e99fcb6d3e8a298174bd2b348dffffffff292e94738851718433a3168e43cab1c6a811e9a0f35b06b6cec60fea9abe0f43010000008a4730440220582813f2c2d7cbb84521f81d6c2a1147e5296e90bee05f583b3df108fdac72010220232b43a2e596cef59f82c8bfff1a310d85e7beb3e607076ff8966d6d374dc12b014104a8514ca51137c6d8a4befa476a7521197b886fceafa9f5c2830bea6df62792a6dd46f2b26812b250f13fad473e5cab6dcceaa2d53cf2c82e8e03d95a0e70836bffffffff0240420f00000000001976a914429e6bd3c9a9ca4be00a4b2b02fd4f5895c1405988ac4083e81c000000001976a914e55756cb5395a4b39369d0f1f0a640c12fd867b288ac000000000100000002c8a8356402b9271ae73116b3a613d0a489aa3441a72d4b53a98eb7837584e17a010000008a4730440220771ae3ed7f2507f5682d6f63f59fa17187f1c4bdb33aa96373e73d42795d23b702206545376155d36db49560cf9c959d009f8e8ea668d93f47a4c8e9b27dc6b330230141048a976a8aa3f805749bf62df59168e49c163abafde1d2b596d685985807a221cbddf5fb72687678c41e35de46db82b49a48a2b9accea3648407c9ce2430724829ffffffffa4f0111c9248f7360b6e3fed4856563eb0aa82b10303c14befae96ed4818c7fe010000008c49304602210087fc57bd3ce0a03f0f7a3300a84dde8d5eba23dfdc64b8f2c17950c5213158d102210098141fbd22da33629cfc25b84d49b397144e1ec6287e0edd53dbb426aa6a72ed014104dee3ef362ae99b46422c8028f900a138c872776b2fcffed3f9cd02ee4b068a6df516a50249ae6d8f420f9ce19cdfc4663961296a71cd62b04a2c8a14ff89b1d0ffffffff01c0e1e400000000001976a914e43f7c61b3ef143b0fe4461c7d26f67377fd207588ac00000000" - btcblock: *btc_full_with_tx_hash - btcblockWithTx: *btc_full_with_tx - mockedResponses: - options: - bytes: - - getblock: - req: - - - method: getblock - params: - - "00000000000000001e8d6829a8a21adc5d38d0a473b144b6765798e61f98bd1d" - - 0 - res: - - - result: "0100000081cd02ab7e569e8bcd9317e2fe99f2de44d49ab2b8851ba4a308000000000000e320b6c2fffc8d750423db8b1eb942ae710e951ed797f7affc8892b0f1fc122bc7f5d74df2b9441a42a146950401000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0804f2b9441a022a01ffffffff014034152a01000000434104d879d5ef8b70cf0a33925101b64429ad7eb370da8ad0b05c9cd60922c363a1eada85bcc2843b7378e226735048786c790b30b28438d22acfade24ef047b5f865ac000000000100000001ad6279669bcc8e3003267d97c9e364a9835ea7a5b53871d057783ef96f468d73000000008c4930460221009805aa00cb6f80ca984584d4ca40f637fc948e3dbe159ea5c4eb6941bf4eb763022100e1cc0852d3f6eb87839edca1f90169088ed3502d8cde2f495840acac69eefc9801410486477e6a23cb25c9a99f0c467c6fc86197e718ebfd41d1aef7cc3cbd75197c1f1aaba985b22b366a0729ccb8aa38277809d6d218cf4077ac9f29a953b5435222ffffffff0280f0fa02000000001976a9146f31097e564b9d54ebad662d5c4b5621c18ff52388ac007ddaac000000001976a9147228033b48b380900501c39c61da4ab453ca88e888ac0000000001000000035a19f341c42071f9cec7df37c4853c95d6aecc95e3bf19e3181d30d99552b8c9000000008a473044022025bca5dc0fe42aca5f07c9b3fe1b3f72113ffbc3522f8d3ebb2457f5bdf8f9b2022030ff687c00a63e810b21e447d3a57b2749ebea553cab763eb9b99e1b9839653b014104469f7eb54b90d90106b1a5412b41a23516028e81ad35e0418a4460707ae39a4bf0101b632260fb08979aba0ceea576b5400c7cf30b539b055ec4c0b96ab00984ffffffff5b72d3f4b6b72b3511bddd9994f28a91cc03212f200f71b91df13e711d58c1da000000008c493046022100fbef2589b7c52a3be0fd8dd3624445da9c8930f0e51f6a33d76dc0ca0304473d0221009ec433ca6a9f16184db46468ff39cafaa9643021e0c66a1de1e6f9a612092790014104b27f4de096ac6431eec4b807a0d3db3e9f9be48faab692d5559624acb1faf4334dd440ebf32a81506b7c49d8cf40e4b3f5c6b6e99fcb6d3e8a298174bd2b348dffffffff292e94738851718433a3168e43cab1c6a811e9a0f35b06b6cec60fea9abe0f43010000008a4730440220582813f2c2d7cbb84521f81d6c2a1147e5296e90bee05f583b3df108fdac72010220232b43a2e596cef59f82c8bfff1a310d85e7beb3e607076ff8966d6d374dc12b014104a8514ca51137c6d8a4befa476a7521197b886fceafa9f5c2830bea6df62792a6dd46f2b26812b250f13fad473e5cab6dcceaa2d53cf2c82e8e03d95a0e70836bffffffff0240420f00000000001976a914429e6bd3c9a9ca4be00a4b2b02fd4f5895c1405988ac4083e81c000000001976a914e55756cb5395a4b39369d0f1f0a640c12fd867b288ac000000000100000002c8a8356402b9271ae73116b3a613d0a489aa3441a72d4b53a98eb7837584e17a010000008a4730440220771ae3ed7f2507f5682d6f63f59fa17187f1c4bdb33aa96373e73d42795d23b702206545376155d36db49560cf9c959d009f8e8ea668d93f47a4c8e9b27dc6b330230141048a976a8aa3f805749bf62df59168e49c163abafde1d2b596d685985807a221cbddf5fb72687678c41e35de46db82b49a48a2b9accea3648407c9ce2430724829ffffffffa4f0111c9248f7360b6e3fed4856563eb0aa82b10303c14befae96ed4818c7fe010000008c49304602210087fc57bd3ce0a03f0f7a3300a84dde8d5eba23dfdc64b8f2c17950c5213158d102210098141fbd22da33629cfc25b84d49b397144e1ec6287e0edd53dbb426aa6a72ed014104dee3ef362ae99b46422c8028f900a138c872776b2fcffed3f9cd02ee4b068a6df516a50249ae6d8f420f9ce19cdfc4663961296a71cd62b04a2c8a14ff89b1d0ffffffff01c0e1e400000000001976a914e43f7c61b3ef143b0fe4461c7d26f67377fd207588ac00000000" - btcblock: - - getblock: - req: - - - method: getblock - params: - - "00000000000000001e8d6829a8a21adc5d38d0a473b144b6765798e61f98bd1d" - - 1 - res: - - - result: *btc_full_with_tx_hash - btcblockWithTx: - - getblock: - req: - - - method: getblock - params: - - "00000000000000001e8d6829a8a21adc5d38d0a473b144b6765798e61f98bd1d" - - 2 - res: - - - result: *btc_full_with_tx - + - + config: + proof: 'none' + input: + - "00000000000000001e8d6829a8a21adc5d38d0a473b144b6765798e61f98bd1d" + expected_output: + options: + bytes: "0100000081cd02ab7e569e8bcd9317e2fe99f2de44d49ab2b8851ba4a308000000000000e320b6c2fffc8d750423db8b1eb942ae710e951ed797f7affc8892b0f1fc122bc7f5d74df2b9441a42a146950401000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0804f2b9441a022a01ffffffff014034152a01000000434104d879d5ef8b70cf0a33925101b64429ad7eb370da8ad0b05c9cd60922c363a1eada85bcc2843b7378e226735048786c790b30b28438d22acfade24ef047b5f865ac000000000100000001ad6279669bcc8e3003267d97c9e364a9835ea7a5b53871d057783ef96f468d73000000008c4930460221009805aa00cb6f80ca984584d4ca40f637fc948e3dbe159ea5c4eb6941bf4eb763022100e1cc0852d3f6eb87839edca1f90169088ed3502d8cde2f495840acac69eefc9801410486477e6a23cb25c9a99f0c467c6fc86197e718ebfd41d1aef7cc3cbd75197c1f1aaba985b22b366a0729ccb8aa38277809d6d218cf4077ac9f29a953b5435222ffffffff0280f0fa02000000001976a9146f31097e564b9d54ebad662d5c4b5621c18ff52388ac007ddaac000000001976a9147228033b48b380900501c39c61da4ab453ca88e888ac0000000001000000035a19f341c42071f9cec7df37c4853c95d6aecc95e3bf19e3181d30d99552b8c9000000008a473044022025bca5dc0fe42aca5f07c9b3fe1b3f72113ffbc3522f8d3ebb2457f5bdf8f9b2022030ff687c00a63e810b21e447d3a57b2749ebea553cab763eb9b99e1b9839653b014104469f7eb54b90d90106b1a5412b41a23516028e81ad35e0418a4460707ae39a4bf0101b632260fb08979aba0ceea576b5400c7cf30b539b055ec4c0b96ab00984ffffffff5b72d3f4b6b72b3511bddd9994f28a91cc03212f200f71b91df13e711d58c1da000000008c493046022100fbef2589b7c52a3be0fd8dd3624445da9c8930f0e51f6a33d76dc0ca0304473d0221009ec433ca6a9f16184db46468ff39cafaa9643021e0c66a1de1e6f9a612092790014104b27f4de096ac6431eec4b807a0d3db3e9f9be48faab692d5559624acb1faf4334dd440ebf32a81506b7c49d8cf40e4b3f5c6b6e99fcb6d3e8a298174bd2b348dffffffff292e94738851718433a3168e43cab1c6a811e9a0f35b06b6cec60fea9abe0f43010000008a4730440220582813f2c2d7cbb84521f81d6c2a1147e5296e90bee05f583b3df108fdac72010220232b43a2e596cef59f82c8bfff1a310d85e7beb3e607076ff8966d6d374dc12b014104a8514ca51137c6d8a4befa476a7521197b886fceafa9f5c2830bea6df62792a6dd46f2b26812b250f13fad473e5cab6dcceaa2d53cf2c82e8e03d95a0e70836bffffffff0240420f00000000001976a914429e6bd3c9a9ca4be00a4b2b02fd4f5895c1405988ac4083e81c000000001976a914e55756cb5395a4b39369d0f1f0a640c12fd867b288ac000000000100000002c8a8356402b9271ae73116b3a613d0a489aa3441a72d4b53a98eb7837584e17a010000008a4730440220771ae3ed7f2507f5682d6f63f59fa17187f1c4bdb33aa96373e73d42795d23b702206545376155d36db49560cf9c959d009f8e8ea668d93f47a4c8e9b27dc6b330230141048a976a8aa3f805749bf62df59168e49c163abafde1d2b596d685985807a221cbddf5fb72687678c41e35de46db82b49a48a2b9accea3648407c9ce2430724829ffffffffa4f0111c9248f7360b6e3fed4856563eb0aa82b10303c14befae96ed4818c7fe010000008c49304602210087fc57bd3ce0a03f0f7a3300a84dde8d5eba23dfdc64b8f2c17950c5213158d102210098141fbd22da33629cfc25b84d49b397144e1ec6287e0edd53dbb426aa6a72ed014104dee3ef362ae99b46422c8028f900a138c872776b2fcffed3f9cd02ee4b068a6df516a50249ae6d8f420f9ce19cdfc4663961296a71cd62b04a2c8a14ff89b1d0ffffffff01c0e1e400000000001976a914e43f7c61b3ef143b0fe4461c7d26f67377fd207588ac00000000" + btcblock: *btc_full_with_tx_hash + btcblockWithTx: *btc_full_with_tx + mockedResponses: + options: + bytes: + - getblock: + req: + - + method: getblock + params: + - "00000000000000001e8d6829a8a21adc5d38d0a473b144b6765798e61f98bd1d" + - 0 + res: + - + result: "0100000081cd02ab7e569e8bcd9317e2fe99f2de44d49ab2b8851ba4a308000000000000e320b6c2fffc8d750423db8b1eb942ae710e951ed797f7affc8892b0f1fc122bc7f5d74df2b9441a42a146950401000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0804f2b9441a022a01ffffffff014034152a01000000434104d879d5ef8b70cf0a33925101b64429ad7eb370da8ad0b05c9cd60922c363a1eada85bcc2843b7378e226735048786c790b30b28438d22acfade24ef047b5f865ac000000000100000001ad6279669bcc8e3003267d97c9e364a9835ea7a5b53871d057783ef96f468d73000000008c4930460221009805aa00cb6f80ca984584d4ca40f637fc948e3dbe159ea5c4eb6941bf4eb763022100e1cc0852d3f6eb87839edca1f90169088ed3502d8cde2f495840acac69eefc9801410486477e6a23cb25c9a99f0c467c6fc86197e718ebfd41d1aef7cc3cbd75197c1f1aaba985b22b366a0729ccb8aa38277809d6d218cf4077ac9f29a953b5435222ffffffff0280f0fa02000000001976a9146f31097e564b9d54ebad662d5c4b5621c18ff52388ac007ddaac000000001976a9147228033b48b380900501c39c61da4ab453ca88e888ac0000000001000000035a19f341c42071f9cec7df37c4853c95d6aecc95e3bf19e3181d30d99552b8c9000000008a473044022025bca5dc0fe42aca5f07c9b3fe1b3f72113ffbc3522f8d3ebb2457f5bdf8f9b2022030ff687c00a63e810b21e447d3a57b2749ebea553cab763eb9b99e1b9839653b014104469f7eb54b90d90106b1a5412b41a23516028e81ad35e0418a4460707ae39a4bf0101b632260fb08979aba0ceea576b5400c7cf30b539b055ec4c0b96ab00984ffffffff5b72d3f4b6b72b3511bddd9994f28a91cc03212f200f71b91df13e711d58c1da000000008c493046022100fbef2589b7c52a3be0fd8dd3624445da9c8930f0e51f6a33d76dc0ca0304473d0221009ec433ca6a9f16184db46468ff39cafaa9643021e0c66a1de1e6f9a612092790014104b27f4de096ac6431eec4b807a0d3db3e9f9be48faab692d5559624acb1faf4334dd440ebf32a81506b7c49d8cf40e4b3f5c6b6e99fcb6d3e8a298174bd2b348dffffffff292e94738851718433a3168e43cab1c6a811e9a0f35b06b6cec60fea9abe0f43010000008a4730440220582813f2c2d7cbb84521f81d6c2a1147e5296e90bee05f583b3df108fdac72010220232b43a2e596cef59f82c8bfff1a310d85e7beb3e607076ff8966d6d374dc12b014104a8514ca51137c6d8a4befa476a7521197b886fceafa9f5c2830bea6df62792a6dd46f2b26812b250f13fad473e5cab6dcceaa2d53cf2c82e8e03d95a0e70836bffffffff0240420f00000000001976a914429e6bd3c9a9ca4be00a4b2b02fd4f5895c1405988ac4083e81c000000001976a914e55756cb5395a4b39369d0f1f0a640c12fd867b288ac000000000100000002c8a8356402b9271ae73116b3a613d0a489aa3441a72d4b53a98eb7837584e17a010000008a4730440220771ae3ed7f2507f5682d6f63f59fa17187f1c4bdb33aa96373e73d42795d23b702206545376155d36db49560cf9c959d009f8e8ea668d93f47a4c8e9b27dc6b330230141048a976a8aa3f805749bf62df59168e49c163abafde1d2b596d685985807a221cbddf5fb72687678c41e35de46db82b49a48a2b9accea3648407c9ce2430724829ffffffffa4f0111c9248f7360b6e3fed4856563eb0aa82b10303c14befae96ed4818c7fe010000008c49304602210087fc57bd3ce0a03f0f7a3300a84dde8d5eba23dfdc64b8f2c17950c5213158d102210098141fbd22da33629cfc25b84d49b397144e1ec6287e0edd53dbb426aa6a72ed014104dee3ef362ae99b46422c8028f900a138c872776b2fcffed3f9cd02ee4b068a6df516a50249ae6d8f420f9ce19cdfc4663961296a71cd62b04a2c8a14ff89b1d0ffffffff01c0e1e400000000001976a914e43f7c61b3ef143b0fe4461c7d26f67377fd207588ac00000000" + btcblock: + - getblock: + req: + - + method: getblock + params: + - "00000000000000001e8d6829a8a21adc5d38d0a473b144b6765798e61f98bd1d" + - 1 + res: + - + result: *btc_full_with_tx_hash + btcblockWithTx: + - getblock: + req: + - + method: getblock + params: + - "00000000000000001e8d6829a8a21adc5d38d0a473b144b6765798e61f98bd1d" + - 2 + res: + - + result: *btc_full_with_tx + - + config: + proof: 'none' + input: + - "0000000000000000000a276fc7641724fe5ad132f598c96eff403958e76667e2" + expected_output: + options: + bytes: "04000020f18c983f6d8444c2797c85dcfea16b1369588c57081d05000000000000000000766d89b9565af1f7784b57ef876295705bf43eeba075f0dac409400459a4c2717163e660ce98131704f180e020010000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff6103b3870a1e2f5669614254432f4d696e656420627920657266616e6d6f73616465712f2cfabe6d6d0fd649a10013c36addb756cf1d9c9218e8df928061dc99646b05a9f16c44301c1000000000000000106d391e0cabf695c5562fa47f7b150000ffffffff0404474425000000001976a914536ffa992491508dca0354e52f32a3a7a679a53a88ac00000000000000002b6a2952534b424c4f434b3a0e83dfab6533b32ac33dbaabffc4b3f5d6ced40c50dcf46ee0031d2a003560dc0000000000000000266a24b9e11b6dbffd356eb5da59e244a03b4144279f8dd61b4bb9813d812c4a9f9a20d99113910000000000000000266a24aa21a9ed2a45c4ead8566147106555d74ee978c78db04d97e716c3b1eac678fb63c78261012000000000000000000000000000000000000000000000000000000000000000000000000001000000000101eda2df1f9d38f3af3fba3a6c26fc7b9a26950a51daed78d423f56bc6970678ef2700000017160014764273e0504b0f3660c45e8ad0fa1ccc33c65186ffffffff01c408190300000000160014508951bdcbdd0d956514e5544cd35b578b11ae410247304402205c03d3214220d20dd8a79849d67d69c778870e693af41c706755156944e2b8db022013a88f61457768e76060fd6e7a80cee5b53106099a53dc5723d54e6573a13c8601210327ad7578e80043bb5b2d51daa7012f433d7c3f34a81b4a506d40b32b24c267a80000000001000000010a75c9cebe539bc0d56c79bff766d4144aa84915bcc95ead38f7f543cb0cae51490000006a47304402206ecc7ee06ed9e5198a69f28926161ee6bd8050aeaf3e7f221d45d9907bd3acbf02203cd7ec7eb88555cf73100522b4ede5c58b9f10f0ccab010c01307866e47d618b0121033ec98c3f20406c8748febca81c0755b46bb128db0142a642f8f447ef4e79d680ffffffff0134510700000000001976a914528dad2141cd58294c0d3d8dd8d322d31995685488ac000000000100000001b8a6998b775445af1f3c24f80240b49106672ee41079f5e18ec0d636710dc47d730a00006a47304402201b42dcbac53ae8cd40a6b7fc9a115278c68cbac9e5dc1cda7b75e66dfc848545022077f349bd2f6517d8b4a95f1640ee871d1f2c48085529da499eaadf52d9ae619801210226fb8a4429f73e7094d8125f8c8f3d9742306edad6bca096f2e501ca8f438842ffffffff01d4260800000000001976a914528dad2141cd58294c0d3d8dd8d322d31995685488ac000000000100000001b8a6998b775445af1f3c24f80240b49106672ee41079f5e18ec0d636710dc47d410d00006b483045022100d0c573af05451873741984fa8bf72ae132265ee13916cdfad90654730bcbb69902203d8c9ae9d4735efd901a97d8792f560eacc7c049414d5cef8c9774500585e6bd01210346702a3a0d900fdc122c7e5514d80f4edb84a2ed5b1c33fa165cc92398806885ffffffff01c49e0700000000001976a914528dad2141cd58294c0d3d8dd8d322d31995685488ac00000000010000000001013564d331e85690e870a3fe92c14e03da258f1cd8272041a9a9483ffcdc3c9d6d0000000000ffffffff02a15d3300000000001600146bb7140ad4c793d14021f48e672c2d266b3270c328d706000000000017a914584e23c934e8342026c14070ea525b36b244d8a687024730440220360091e4ca5a9e4f25eff0a9139123859499b69c5f8f1f48380eefffff3f2af402206a420e59a0373d450a94320e893500898236d717805a140ab6b64be5988c5b18012102064b8200ae425f73ac9a591094e4827b1a83ad6c44e8c8c7ca231649c0d189d90000000002000000000101c514a338814a76d26c805e7a5dd8be9f25e23934034d683dcbfedcb572d7ac330800000000feffffff0315bc01000000000017a9143b956676f8748666c71424b301a9a1d4554e0849870c9ac51400000000160014ff955c763d5c6d5092e121ee42e806490704ecfc400d03000000000017a914e441bf8eb1b00e1e99c07984aeb5d1b23b8c26cf870247304402206e1c1909a3cfff3f7f2ac82ebcb90fcdb3d9b07c8ed95d0a10478664f7d160c60220689aebf63dfc81d234298ad3ad8265f349039bffe243f9ec103f0821accf0228012102eea9ba79990ec589ce0c60d895ae5283f933e98b583872f0e3e90e795becb897b1870a00020000000001019d320941a891cd54eebb433eed3baaf09e0f06c0b283238cc5163e25a5939a6a0000000000fdffffff024cba0100000000001600141debbd78f6e6734ba3ad902df3781d8010ade747d0db06000000000017a9147b9a9e6d60400e5deb08c2be1a72a4afd411337e87024730440220307ddd38d20a7214177077d497424f77284c7846477b8882f26c82f928f7e4a00220643c16e67e1397749732076c03355f9b0ef1e4ef27e3953c986f439cff94ebb30121020a820f6114b3cdf4d761ca1f31aa2d9dd19ae4c7eea7e694709b9ac94a4455ccb1870a00010000000001019e3c5f66d7d0519b53491fd5184a8c962dbef84f5e28197959815c5fbedb8d4d3b00000000ffffffff32ee6a2e00000000001976a914c378ded906a60a72b6345b5eaff0d933427218a588ac7c0a180000000000160014cb60668f051c001353e14e4218806911879e934ef41d04000000000017a91453e13860d18555d9d2d595c8df33823a177d40ee87e72e16000000000017a91402de054ac7322088ff02f28d09f4e24653e870b7875d1f0500000000001976a9146b6c4f33d3931c52cc3760e0e864ac905b5aafb088ac902702000000000017a91403c04e312012941bbc2941e2a1c9e1db3f58e741876cd401000000000017a9144eb5ef7073cfa46e1dcbd432e5461169b69d87d18777de00000000000017a9148b219ff8975fdc4e92e99f2adc52396cf86d23b087e04e0000000000001976a9149a716a4e526dc3e1ff3d8fdb9513d21a584bb41f88ac7b670600000000001976a914e739159436dcac622b027fc8fe03266a940ec82188ac563001000000000017a9145e683f3531dc04fbfd40f77375e920d5d241a95487930a0100000000001976a9147762c98e0e3367094084716de9c539d489e6441788ac283a0900000000001976a91408f99e916e4cf152e6a241c05c79cedc0908486488ac747e06000000000017a914d3f1766bf4170e8491e522abc5f403c8c5b00cb387a25504000000000017a914af3ed025d98feaf94600c016bc71023edc305273871d2609000000000017a9147fc5ada0ec0d456d5c5b58fd21b7968bdd7a02df876efb5f000000000017a914e0e95aacb6866119226c2b391fbb8e165e1b9c87876bd00000000000001976a91451564fb5db5530ec7d6fa333647a01af7380d21788ac2f5cab000000000017a9149501fed908d5114cedd9386660873e62ca2f3dff8745da06000000000017a914b83032f7d5cca0051f788f1a2eff90ab2d79e3d48720cd0800000000001976a914eeb8bacc9220f59abb663e432985ee200d427f3088ace2580400000000001600144a12310c411a22a565621fa258e8426bd7c8d0b3e09304000000000017a914d5d8c6caf78fc21061fc4731c24b0c89a36c7ad687f82401000000000017a9148289e1a729717438ebcdf8c9e07596ec2d3acbaa8761610400000000001976a9146451b87e24ca86905eea9d851e28c5b8aa9dee3988aca4900200000000001976a914d37556e83e286f550870db5c825e6fffc312e55588ac8e3a000000000000160014353b138c3be7387ddc491c83e7159d736c537de1c4240100000000001976a914845c12e6aedc4cdbc79f2eacce9ca30d631b9aa788acb43f0100000000001976a9140e09830988a068eb6507dbae420639dd881b47c488aca0900200000000001976a9147e66edc27e301deb97e19ce70e4204ea670196e188ac473601000000000017a914168046f69a90adcf31e4ed4dd580b643894f3815879cda2b000000000016001423b91d13fd85c250078bef3e696141afbc7d67d7af5d0000000000001976a91481316d20a965c57e365ddbd88cf0b33df182497c88accadb00000000000017a91440aa6e55061da5ef2b270b375d169df7d578785a87805804000000000017a91471084b0c6799c2db9ad5ba2afd88af69cfaf38db87af5d5600000000001976a914fd61259381494884b2094a6c7e015ecf964dcedb88ac80580400000000001976a914d3e27eac3b18ab2fe0e543b0e24a457aba4508a788ac8b3a0000000000001600144bf26007bb626433beb32f46989c534c0ea36b94929204000000000017a914fec8bce62d0b8caf0881ce3596c1ca37d48df3ef87682a5d0000000000160014715f70274118762b58a11dcfbff636faa4be8a3d1c160100000000001976a914cac8f77da9673a862a29d6e24f9a0a3b4d6285d088ac436416000000000017a9144c79e8d15a93ef96ffe849ff1d013907a71f29cb8709340400000000001976a91493d66c36e24f6750c3b1f714d26ccc06e30f8c0c88acf4270200000000001976a914670d8e194515294a39ca836bcd89c5e63946ad7788ac37790100000000001976a914bd744f75e1051670b45ea769f2807ce42ffc376088acfa510000000000001976a914a2f869675fc607b7e32c21536b8882781057f3a788ac893d09000000000017a9140cbf435d9f011cf09c193a18c2c69c8c1319d5e0872ada07000000000017a91472b85f3d0b3091ffe3e1e33499bc850cb2e1bb628761390e00000000001976a9149fd915599b7f06b822f0296bd90abacd129f4f7688ac93fd16000000000017a9148f9ef19321ad0a62eeb1034ffc41303658095a91870248304502210089ca3893f1180326d1bbc27f89b23ce5e2ef4f35c9130eaff088f0484896c08f02205559db4a068aaa1547972e18ce77181de04206e8d2e2a4b2bfcff6a531cce199012102efd56b2aa9c332bafdadee106a21d3feea0e93e83b2c01e30172719b5e5a0e0b00000000020000000001019a8675f3a64ec4f2b6bf108d3bf00d3d0b332787b4a4a3a307af3d53fc4b2cfd0000000000ffffffff01c51a0a00000000001600146c18ac26595dd955b85b174a3d8c78e387071e8c0247304402203822f1f9b7908e8e80b3cb4a655cb80425feaa04319098af909d640bfc07e5a30220071eeed6e1f86a8fba49c6d29eeec5487bcf3c8d6833d0c181d41baa374ce950012102de8829afb19976f347b0f0b6fc27117abba6a336366aa16c0ffa6fc4a456afb60000000001000000000101e87926c591f6b4835afdc422aeeec569fd1fb35b1fadc16ec5c4042b3e181e2101000000232200201050f81f3cf192e8c5f1923700e7fa222aa2d4845303a4087f019408d972fd12ffffffff02843a17000000000017a914dfb610f26c86fbaab363c3b264bb283facabaa5887fe895a0d0000000017a914f02f35dfd649ccfdbb1e9a19156c3fb99a0d13ad8704004730440220077cd1a4eda2fd2251bb4e88fe9cb9abe73c40244c61916e54e19425ec38f43f02204c2ead8de4a7f7e537e2b71a0dd831d20d6f8fbfd0ad957221832f1a5ee884de014730440220187cc4f3f86a1fdb8dd9e688f85568bab932e4347fef9e1f052a8e68497808530220328c1918fec26d10a81d938bbb5f708eacd39884d57e60e0fa23ebad1c530e9301695221036414da3ee01031b225fff42f958db3f35064540a820a46dea3c5af79b1ef6a352102fae595ff8c0a41acbd2533e211a0236626b903472dab1c79cd3101c856d01faf2102c94ac1e83cd87f7566251b51112e20d79c69cc6d6bfcd5b3cbba3428b6ef2b8653aeb1870a0002000000000101a5b3a22222027d823b10ea60e917b4b5bd9e9d5edfa8f09126ea9305e2b7d7080000000017160014d8e7dfd2980abb8a17160af2eb778bed171f51a4feffffff01507d0500000000001600141d4f2ad2a9e6d7ddd83469425ff59441e4f9eb230247304402204c5b54e1026e7b8e424d10a1e7fe55c5268e27350beeb3195e3e92623ba1c14f02207448cca3450a71f5ca7cbbbf95e6022afdc964642f6f0bc8f0513677e8373eb90121021b1654ea4843ddfbf7c2c9bbdd0add4f81c1789b4531739c07bc169b7a523bc8b1870a00010000000001016381ce29bc6617456e1c212160df77cff54afb66d41634669ff5e57e2f59b2cc0100000000feffffff0204750000000000001976a9140f30034977561e424564ce8eca6554f721693f0688ac4226000000000000160014ce5bd11f4c403d73717538794d0d9c333c82585c02483045022100c8f748b7101f2ff35c4a80be66e31e131f19c889993e3b1980c4e87bf049b91e0220432099cdc708c333a1c8a79632b01762a7b10cbc2224d0f2f64ef896e7e98108012103d9ac44f61276f12807d3a66711d4a9b385fab4fd24e61b67de3610d5bbbc4d580000000001000000000101872a188b5c43f8990f99c10953cd72c9956ed89a9fef67b3424961cb99dcbd6313000000000000000002671700000000000017a914c1e70061f0c8d24dcf42b1dd3ee7749c841118ba87c32311020000000016001426da8ead36f9cb7232885e24bed55db638983b8302483045022100f2d38235d74912cfad18a1bbb834c29a330f15675b159157749a9c88d31816b602206a161222a42ede172d15c88141d812003dfdbe519108a94bcbbbe831a07e4b1001210330d24edc6c5646162672257ba2689297ecbc59c8005952f6aea51198df520d6c000000000100000001bb96ddbd2666d7c62f72f824bb6a8f8cee2d1a22c4b421afc9bb86e1b0bc27fe010000006b483045022100b3299607ff35cfbc2017b1841aa3d31c27f9135a008b949481357c013e061d560220748e3af715112ac5ac189a1328ede5b98f157ca6fd62d50f691a5c1b6698c4c20121031e9a636ef528970636cc811384ffde2a2c6d131a67d02e8e082b0c09c1669f5401000000020cdf0600000000001976a914b1da96c6d9f8ca1df601b6f0b375cca783a4de4288ac69acac02000000001976a9141e7c72c338f790b929422397218d8785a4aeda6188ac0000000002000000000103b8a6998b775445af1f3c24f80240b49106672ee41079f5e18ec0d636710dc47d9f0100001716001469c11bcdbf3462cf93c59b8005afcf0b524eabf0fdffffffb8a6998b775445af1f3c24f80240b49106672ee41079f5e18ec0d636710dc47d140b000017160014b016e01e92bf06c9be72807ac0fc4bc7019f7f30fdffffff9c4bb54d5060d1472adf4501099b49061beaaaffbca6da34dcc4532b4fadbfd32b00000017160014de89107b16de1d796cfedc3504dad23319499db9fdffffff0130ff2d000000000017a914cf3fd4edf20dc374e92523385f306553c0a43dd187024730440220531ce32754eb3f2a514e222d2f2cb831f07caba2f6ea6ca6ac5728f64b69ac4202204e20882cfe413982a6a04464487c7b7794f2f9bfd90743d18668378bc4be91f5012103abc33ddacdf49de4b23dd1129d09447ceb65c63d53fde522eda5ea02769548a9024730440220053eefd97e286c0c36713642f4845e19e4cdde2ef69dc598fe075c034b291cc702204149106ea978b851607830d937900c2c72a84b07244ae3341f12061139c190a801210210527396e491eadb17a4fb4a8c8f565c1479df2792ed9ac054e88deb8e263fb002473044022014ab0be12a8adf968e9a4491588cbc1d253be126a77c615a3d9fb6fd31de2d3e02207f03060c5fe44081d2b19ca6688e71e03d611bbfe516310cd711de5b3659b417012102c2faa9505090a725080ef731b099fd38b525b14c291c78dc9c15d8355bdc91a9b1870a00020000000001016f646bf26972b886246bd126ca3ce494fd8af18cc8f11b2a0c1eec9846061e45000000001716001480090cde8f2563879e0108a6b729178c4ff91d7afdffffff027da704000000000017a9143831317df36b605e41b860c0ac218542cd85808a87510e62650000000017a9141ba7a9a53c05d26a6983f216f4d1205634ac80fd8702473044022069ee012d64ed6d2af86a0cc318a419218717b9d4607fb6da3fd4233e7ef44b7e022002c769b0b9bd3d664849e73868d77efc4addbe1d41c242d901338a5e6b73a7b2012102dbc646d2d44ec390542a4abd6902c387afa9e4ce559b512343ed691fc481d8a1b1870a0001000000000102f9d6feea9503d67b39f794086cda7d5e68ffb686da541e9252b00575804b6a7a150000006b483045022100b0e1f5e48421310cc6ae7ab8aeb701ae2aa3529da7707355f3783ba7f83f10c002203305e035234f70d40a2d734520c10eaa96fa2e102f38bceb172a64fbf9291a94012102e68bd9ba1d05767adf0c3033c4a6466f815ad597e14ff85cfafc75570ffa1245ffffffff2451e3697747eb3a19ef65addf99fdb0a6b8b9c63da4af2f8ea147849433161f0000000000ffffffff025b1e00000000000016001410d60ff8a884cd7fd25248d0530bd5af1ddd68b9552a2a00000000001976a9141c17013569299a011183890111b8d49fb6038e3288ac00024730440220182c99a1329e72d102c1d82eb6cd09ac563e46384fdea9d7853294ccd7ac2ea902200db86458cc3e9e49904e5f35272015f7b4db7701fe892f38088b3547a0f837a1012102471061ab49123d49c68003fc6aa248d5653415400328ab52b0d1a63b6b13d88c00000000020000000001063c87469ed6acc80fe4dadc6e76ea3a12977d886f904b1d089ac2ea6f1798a64e0200000000fdffffff662e924fd382017253e8d3c391fcbb1d9866ebe42cba88bcc3b026556ee14a820000000000fdffffffb5be33c0ec146f30403b5d17e1e900841a14131d0007e7bd9035d69f214f84820100000000fdffffffe5cf501b9ca4b082fb046aa98df4e804776d3ca31291b2504f5e8a1bdb79dabe0000000000fdffffffbe54fc937a033713aa31eefdb9ea9f2aef3e0a1e3e6e10637ded03bc417abace0100000000fdffffff026b83c781488ce17704306f1d64e3a666f6a83e936023532f7be75aa555dcdb0100000000fdffffff01977f2f00000000001976a914561c8f5dcb731ccb9af98393fa0e2dbfbefd7aee88ac0247304402200a7201ccebb8eae607f01f1e73dc43022881c8fa4505e5cf7d068dba2d9f10d302206084c24192f6ddbd04b00be4d7addc5d5a6ea2fe3a4734bb3bd021017e4015b80121037bdada249cff349769d9ea6d2efe5d76d1e3beddac5429d735fbe7f6553edcd90247304402200e6adcc67185f0f8c12ab99eadd6f36a32f187911af084bd021a6240156ce68f02202d461ea2bc4509145cc11c6f69ab2db67106818b132288be637ca211d6ff024801210373e81d5ad095408ff305fcc7c2c14c81e6fa962c50fe3ffa1bdc41e1890b17f20247304402202db1cc195f387ff5dbd4a79fbaeb8e7dd7a4990a3d4c47ad981ca6f3f3768391022068d94d5f29552765be2e311ddf6761e54f378f9414602b913f7c56076faecf2c012103cd29ef645c1948fcb04cec63e7a45ccbc8b65497616978b6ea8ae13fe4687bf70247304402201dbc1edb23acc6adcf6e631822d4abd4f797055bce1e65cbcc428f75757b853202201f958da9d493f2ab806d58fdd68e8f6c29274d29d0b8ebe72d73acf52ab986db01210273e4e29485a8da1af6695d4139d256b79e58aec75e75c77143f5241018ae821d0247304402200760498a6bb830bb8ae89db766df42e9ac64728687f9e91bcacb77af0fe5d06a02206a808a0c60b894677a149f99ffad087aa1b9f17fe238c11ddbbf6b1a6fb9a3410121033461ad224af04730d6fdfabca98252076c3ae3806fca31caa878f08458aa38cc02473044022004803fb767a77e55bb5d7911f43b890ce63173a20c8083927cba1c63e624d406022054dfed5ae4b5aba3cc46da6f3d1a066ff336d252e54742f85f44d96b24243f01012102063a9e0afe23cc732864101599f8d07be84228f89f838bff29494075f02f39dab1870a000100000000010190d17c5ec983685ae455910a8588a68c49b3c9792f986a68c9e9b64e6d1d32d902000000232200204c17874906b9b484cebc0fde0e7c44705050792b90492bafb7d7f732812d3ce2ffffffff02404b4c00000000001976a914a250d351fd042f41ab739574b9a2d0578ab624bf88ac07eb56080000000017a914a2ac5855a64ba9fe3d808114146e1b440c4b3525870400483045022100c0c650cc00bcc79d1f9fcfed118601c51682df4a17981afa6668adfc9804af7802204db5bef84360e19c97abcb2979d866766d5bb7c64a2801994b6b23c8434e4e770147304402204faa619c7fb1cc4838ed885793cb8f7cbd9520aca90f80047e28ef2214dd2ec3022074dd4fab67a11ce003e92aad6c5daeb2ca52e0d5c81c8a85106479cc205dcda20169522102f86574bbff94767438fd14e8c27e4f074200b351f520cf44cbb182843a3a8d6121033df348ef562e41a2a38c3fc1ccd38a3184c04671f0dd9dd83cb8f0e03ec2708e2102670a229788bd59d537b0379739daeeffaf9fcfe7c411fc8cb785a0a586664fdf53aeb1870a000100000001e9860bc1c053e376100a92db44dd0eb3d6241b851955ee2db514894ef3cf51c3020000006a47304402200fadb0b7d19d0aca703a203ba612c3ca72fae86e863947ad7d6ea5cc628050a302204a1a3ee196b09e63ed6201af722d213b8bcdf3b2d935a6610450524bd72d1e8d012102936c15394948d03a7ba3d4a7e7c7523e14194b3ab808cfe5baed526e15bc0651ffffffff0210a64709000000001976a914c8a6bc95dfec3fa60785b300278d5378c6d453a088acf9de16000000000016001419dfb6e485d667649eb9027c577fc051dae71f0b0000000001000000000101bcc3cdb83fd60ac062fb15f3c8d9852d39fb28a6575b68314f1598d96a58c625010000002322002028cdcdad4c4a07bb6ec5925f2196c4e293898127650b3044fbdb6bab317a7099ffffffff02cb7c0600000000001976a914178412a75e907720a886591d008f10f9f3466f5188acecaf57200000000017a914ba695f1c0d90e1b0fbcc0f1f4623b815848a51f287040047304402205797dac01c67c55dc766706c6cd8f5a26a30dc98bf05f2363acb9b9bcbbf317f022018c7e041a3a8b1f1b54a348fabaf6109a4f3d1a5f58f2ed55ac98ba372ede53201483045022100b6a487645eb046b8dc028a7cfe758bbb03dea784655edeb443afe89cb61d14c70220655df45427eea9387e776b8ad7fe848fd9c215de8269f0348d381c4a0b1251170147522102ce06807bdaf64c3f40d3e4fe990910c82e8b8c3ac8df0c3cf373fa72823f958321039332e240be260cc87f6b1bae52aac5e37fcd61dd89849a8113f14d977e5f39dd52ae000000000200000000010125059190c84b24749e2558c92f0fe049369f07a6ffc5e4f72d9718aaeaf31a7f0100000000ffffffff02fb420200000000001600144e11f3feec543860df274eeab67012608ba939964b490200000000001976a914ec03ec56b76c9398626fd14e17ea23c5e6ee018888ac02483045022100a06e32275e2398421c06b8a2e05716435dfd3d0338115c0121f17611f9cae15102200c7e7429ce64879c9a668d600185b8692aba933b3af2cb0d1bb645268452253b012102bdf3289ab542598c6cbb9d5fe8f07fe31da4495203061a11c9add18b57cf0c4b00000000010000000188273ebd36c7147382027c43325fb618a6192a5a5e10e25072e3c19e696ebb86010000006b483045022100f08866af42bd3b4cde4e0322aef9905e7e91b6f2fd6f74e07f98c4650c9449f502202419439695dfbaf00a43788de8ba6db011d19022f3c0f07dcbf7f712aa70cb42012103f9d3a6ee01d462dcd9e9833150169001afceb41c1076e08a2f435b59f8b1261affffffff02a7ff2200000000001976a9144a58af826227a82b45bd48a69c0618e5f1de0d4688acdbc30100000000001600145a4f089fe01c25c865b23ee7eacd0ca7cf76e5e7000000000200000001b1410d3e8d263ff4a268b53e2e722946e4260b2fa0cec06a8fa402a9ea22e7c5010000006a47304402204782f4a1a2ebc065ed1ff361784f2ea79242bf3f1c9720317754478041a734af02202bcd541b4e7b6b232a6b62a1b8679508b1e27e5e4f697b7f9a5d5fbf18a76387012102b1822ad675522904b61ac135b8a9d36e9b28a1c13b6e54e7e281e746d4d0bb73ffffffff026fd62d000000000017a9140e9259a0faf3c56342caeeec43d61e2184a1144a87884e3a01000000001976a9148b41c041d8dadc41d3efd8b0d430ac80274377ec88ac000000000100000000010506ebe3e53c05518abb9e265e104daab7271f9bd2283d655dc56108eb41eddb5f000000006b483045022100cb23733b6e14b9ef5381db429cc02bd7dcecb2ec620981f17e3cf9d007852d240220090f16b37f50daccd81cbd4b1a154263f9100ecdb76a7ead967f26d280ae9c1f012103da3e84d6d636f2022282db92433773f703d2fb738fe59a5d77da5adc3e2c7e1dffffffff73c175c9f8f657672be8061e079ba63efa89437b1fb693855e881a7964fd7e25000000006a47304402204d6c6a89b44588f1fc2d77f01217eafa122d4c5487e62026a7a5d56f1d1ca119022002239b5f2cccf82f2bf0b7c8621020bc499757dcd14b126906503599c425a3a301210387114296e1c4edadc0c47482b0961e8c9ca37ea256d097c2b49583f19ac59856ffffffffb17008dfed5fc8a91c031cc99ab30c321be4cb33d273c6c6e56b9daa38125c7b0000000000ffffffffb448c7e822385d22f46dec833ae53f83cd3ec3cd0b0f5b77973bd101d788896b0000000000ffffffff3153e6912d9b669f2c58d974b44585752ae7f6b001470a4cc40f2a0d06509f6a0000000000ffffffff01a48779000000000016001436552a1c649baccfee51d6bffb1951e3685ed692000002473044022041bf6e490c22f9b2e817322257e269d712896091414ea5444098815ec8537fdd0220280101a6b811d57b79258b36f69bf4b16bfec35b96d75ce80f83de872884678601210363e40bd07d4ef8b06aedc340b7a0ad588d5bee7234b74a69313872cba2d0dc2902483045022100933da4eed06a472c7a8911b9885ed1e25675c7f6dbfdcddc8a2be437184dade502202a40b5b2a5f6a647d01b8f9177f89132947b39e0ec7f4d60bd1ad1ec504d22f3012103093f9569270b106f0b41cf96e56363ef093b90d1c97da552322f7e67bac7f151024730440220097003a8faeba34e9118b16920390ab2748970ee14c8ba484e691173330eea5f02201ca72e92ebf06541d91499b81b8f4f5a322997f610e06c16cf0eecf04c621cf9012102f8857de858c14dc3836b026ab88b6038f5716f923275d40fe7207e43c687bc60000000000100000001981c89d9e62bdfc5918094ad88ffe9bfa272ddf8f796a5d189874df57c1ec07c000000008b483045022100ba0fd24606b8c9480d28478b40486dbc0c830ac11ad6f56cdaaf3273026f02ab02202c1e0673a2dd7be785425c83bed148890db59d51377eb124e4beba068b239c8e0141048454d039fb7bde4e32c0fccd96dac9a7de33879666ee3ed2e9c88971ce4ed9e37b2828d634789b222c053f6547e6ecdf4869201e74f72267f48f297b7b644339ffffffff01a4ee0700000000001976a914c248b989aae8d90a6242da04f19fa912dc6e8f1088ac00000000020000000001034afd8a48de844106fffb892e53d6269a84b72e0a00c1e94b7175ab0bac46902a0c0000006a47304402204378a0385b713cb38224082a571a195f44680607480be725a7caa7c2ae74883e022002f72e9c716fe958f0346270c7225fba8ed5c6e5e5e4fccd9d0b18c5aed34a71012102a3576bc2466fb6233dadf3df9ce7c92f93965b56b2b1de17ecd933de21eb16b0ffffffffdee1f0b61569b67d592a66c27f53b4164b08bfeefb46b1bb7cdad9a4f65ecb49000000006a47304402200cb20f9b6e76cc4c37dc4ce8899e556726dd475e5115e381b8a980ad0a95eb58022078e5af79d0bd41ce07568eba335123dd17c1f1aae8d0c87377368ad4cb7e0d09012102a3576bc2466fb6233dadf3df9ce7c92f93965b56b2b1de17ecd933de21eb16b0ffffffffada8e51e20fa6b9dd10e95cfc36d2fa3523cfef06bd230d247f3bd47c97d54550100000000ffffffff02a800360000000000160014de83d2189cedab4d984ab78488f00dfdf5e3287015a80e0000000000160014ea01e04aaafa8255b47ede6648e7a0c111431bca0000024730440220673f1e40d5977a114633e8822c520bd0b0d96a83e0b0378a26de89ede6c15d1102201a0989d550e84cfa342e5bd8ed28b364e0c4702c1f271245bb3277b6ae204e5d012102b648eb3b32f72dc612c0412db37bba2ac30c44014e7a7581f52ce54e4d67b9d800000000020000000270867509979084a1d4b7d68f98da815d0ea4bcb0ad6908d0d26bbae80814af76000000006a473044022048966d6c364ec2cbac56965426a62ad8ff0055fbdaef9114da883b9f99baeb300220484dc01e8f5d71d33b8e6d09c5c5a4051a8ca0613e1dd41318e9a1eec955a6ae012102537169a50154c653f1f9799cfda9ea4440108225370cb3db520a0e260ef4ef03ffffffffb4d85fc9249012ac332342c0c1a0d3861c988bf7c7de7de8924a54d486c0e779000000006a473044022001f390a3895940a9c777c0190c0f54716c2bfbd6a278458b7bbbab1e9a974b1a022001d553243f0f025ed609fa2519015682b8c4fe8167cfc5eb2ff34e107ea38708012102537169a50154c653f1f9799cfda9ea4440108225370cb3db520a0e260ef4ef03ffffffff027cd92700000000001976a9148bfc0653d121bf6367c9b78f0f12c3a6880bf16688ac700a3000000000001976a914205826a3fb33a0fcd8c8e177247b48877508260f88ac0000000002000000000102e6a34cbbd1f88e0ea32e013d0e19a150574b2963eeaf221fdca1ea9673686f870100000000ffffffff9ca7b679eb638ed3e3dca3855f2a761b4296a0471ecac3c769d64bdd4e54e3070100000000ffffffff02a7931400000000001600147eef9a2c606f75f7ee5995b6b5a65ee512e08451e3380c000000000016001459f627e531193db7f3a525ae32df9eb45370328402483045022100c99a034876bab21f203f6a8c0f7de3c43ab2aea76e8a2747c39dc9440eb42882022007a636ac3e8f822c9843e8ab2a03792657dfb01703009b016cd778ecd50bf9590121022ee959f516a8d466b32e0a856411a389ea452c8a3b82b12f2f648aba82e00562024830450221009b718162daff3ee7e235371b022d23d0592ab019671bbc7d3cf172a72a8479860220745e9050835eff30c3d7d70cddc84632819d110a3a6a245abd42b9bae23bba18012102cc4a45037362de7a630870382f1fee915a1dfcaa0d1738dc9b503eb7726504b4000000000200000000010152caade841641f3e524811e1608665cb73b7ac25f3a6c0211099c527de9ef3bf0100000000ffffffff021eea00000000000017a91469ab330f75fd4cc065a2151a3fc7676fefb8a75b87157c040000000000160014c4485c0c4bf12c3eba18a86c35611662f9216d6302473044022020c878f15145a3c407126a712862a19e8d0c6066ae26edb100dd8f2ac410bdfe022034d547cc3e9fc059b4c4ca52cca2a6a4c44c34d563abdda59738dbdae08950e6012102b86fbb247c7a6ae45aac84f5633b59ba2a09a3dd09d0fe239d36e202671049640000000001000000000105d8408fe9e041895ce84841973e6ac8e409e19609fe9a8046c0832ed80de0fa0c1000000000ffffffff823ce480f39394b57dfebbc460885f6cc71e7a7f5fd3029968bcde1a13c3e6680100000000ffffffff336c4529efcf90081564b918367726e2017356f14a8ca3cd728ddee1c541488f0000000000ffffffff63b40591ea0521a641e20612fadd2e754531b4358652b86e7b155a539915e9a80000000000ffffffffaff699e5b7c959904b5622340c0dfc905d93dce50e7de670eaa6042b7c5c36d43b00000000ffffffff0540420f00000000001600142ff099afd4dbc6506ad488760a39574d521e51b840420f0000000000160014ce6fcea06b82087b16a78a8372b3c6b3a961e76440420f0000000000160014db151b79d83e1864c0c3d5541d45ef9f2c4d219340420f0000000000160014f05fa715a390cea1736a7b2a0259c23c3d77c4c040420f0000000000160014f18aed18bce9d56deb56115cd351fbe9990a7a5a0247304402201147a76e63ed59be3cf36ca41f0a6820a54b36b05ac7fa0754bc73f584f80fce022073bc8f2af98b17abdf25add10bb518201b99398940f86a769760c011f1e4d5c30121028660ea442a740bc31c79c1b4edbde91c0ccda97fe43a8f32c4116daacbce632d02483045022100e3a3598e60387c3494fbf2e554ccd66d7535ba3f5f611c2cf94e5d76d318e77102207987a0d22c313bf95eade88e076d4a4a9d180aeb160917024426ad2502855077012102899f0e9705052e458e67339e9812535f648fdc55242fdd43fa9474387745f44802483045022100ae8235cfa4affd0a3c27b9ea2aef31eb6155ad8362b6ec2708299a6e4f3ea60202203d1f2d2cc993be5a199df912982d72263a632c18bfc69d00a09406acb1ba67470121023f578ac20dfb94d1ccb0d067f4e2f610006ac2ceeaec39f74fcaa0cb515cef4602473044022064a248d9b84e327eaae7dfb7394281807d813b52f955384684842f523462024c0220544fe4345f8ae496ae26cff6eaaac607fa6495156460ec4820f41fafe6d08f87012103b61a1d01ca68ad214724ee0df5d96b201faf16dc3abc02346d51c6c097211cab02483045022100a40cb59269085e50bd95c4d83a814cdaa9d0923dfbbbebfa3ddace33e567a9ab02205aa027d73e5896b125ce43943a45823710f43402f0a998cee9ca3486945197c20121037175a85efd47494b868919a5cd31e909fd5b3be180c1117be5ebe7b2afabbcaa00000000" + btcblock: *btcBlock_segwit_txHashes + btcblockWithTx: *btc_full_segwit_block + mockedResponses: + options: + bytes: + - getblock: + req: + - + method: getblock + params: + - "0000000000000000000a276fc7641724fe5ad132f598c96eff403958e76667e2" + - 0 + res: + - + result: "04000020f18c983f6d8444c2797c85dcfea16b1369588c57081d05000000000000000000766d89b9565af1f7784b57ef876295705bf43eeba075f0dac409400459a4c2717163e660ce98131704f180e020010000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff6103b3870a1e2f5669614254432f4d696e656420627920657266616e6d6f73616465712f2cfabe6d6d0fd649a10013c36addb756cf1d9c9218e8df928061dc99646b05a9f16c44301c1000000000000000106d391e0cabf695c5562fa47f7b150000ffffffff0404474425000000001976a914536ffa992491508dca0354e52f32a3a7a679a53a88ac00000000000000002b6a2952534b424c4f434b3a0e83dfab6533b32ac33dbaabffc4b3f5d6ced40c50dcf46ee0031d2a003560dc0000000000000000266a24b9e11b6dbffd356eb5da59e244a03b4144279f8dd61b4bb9813d812c4a9f9a20d99113910000000000000000266a24aa21a9ed2a45c4ead8566147106555d74ee978c78db04d97e716c3b1eac678fb63c78261012000000000000000000000000000000000000000000000000000000000000000000000000001000000000101eda2df1f9d38f3af3fba3a6c26fc7b9a26950a51daed78d423f56bc6970678ef2700000017160014764273e0504b0f3660c45e8ad0fa1ccc33c65186ffffffff01c408190300000000160014508951bdcbdd0d956514e5544cd35b578b11ae410247304402205c03d3214220d20dd8a79849d67d69c778870e693af41c706755156944e2b8db022013a88f61457768e76060fd6e7a80cee5b53106099a53dc5723d54e6573a13c8601210327ad7578e80043bb5b2d51daa7012f433d7c3f34a81b4a506d40b32b24c267a80000000001000000010a75c9cebe539bc0d56c79bff766d4144aa84915bcc95ead38f7f543cb0cae51490000006a47304402206ecc7ee06ed9e5198a69f28926161ee6bd8050aeaf3e7f221d45d9907bd3acbf02203cd7ec7eb88555cf73100522b4ede5c58b9f10f0ccab010c01307866e47d618b0121033ec98c3f20406c8748febca81c0755b46bb128db0142a642f8f447ef4e79d680ffffffff0134510700000000001976a914528dad2141cd58294c0d3d8dd8d322d31995685488ac000000000100000001b8a6998b775445af1f3c24f80240b49106672ee41079f5e18ec0d636710dc47d730a00006a47304402201b42dcbac53ae8cd40a6b7fc9a115278c68cbac9e5dc1cda7b75e66dfc848545022077f349bd2f6517d8b4a95f1640ee871d1f2c48085529da499eaadf52d9ae619801210226fb8a4429f73e7094d8125f8c8f3d9742306edad6bca096f2e501ca8f438842ffffffff01d4260800000000001976a914528dad2141cd58294c0d3d8dd8d322d31995685488ac000000000100000001b8a6998b775445af1f3c24f80240b49106672ee41079f5e18ec0d636710dc47d410d00006b483045022100d0c573af05451873741984fa8bf72ae132265ee13916cdfad90654730bcbb69902203d8c9ae9d4735efd901a97d8792f560eacc7c049414d5cef8c9774500585e6bd01210346702a3a0d900fdc122c7e5514d80f4edb84a2ed5b1c33fa165cc92398806885ffffffff01c49e0700000000001976a914528dad2141cd58294c0d3d8dd8d322d31995685488ac00000000010000000001013564d331e85690e870a3fe92c14e03da258f1cd8272041a9a9483ffcdc3c9d6d0000000000ffffffff02a15d3300000000001600146bb7140ad4c793d14021f48e672c2d266b3270c328d706000000000017a914584e23c934e8342026c14070ea525b36b244d8a687024730440220360091e4ca5a9e4f25eff0a9139123859499b69c5f8f1f48380eefffff3f2af402206a420e59a0373d450a94320e893500898236d717805a140ab6b64be5988c5b18012102064b8200ae425f73ac9a591094e4827b1a83ad6c44e8c8c7ca231649c0d189d90000000002000000000101c514a338814a76d26c805e7a5dd8be9f25e23934034d683dcbfedcb572d7ac330800000000feffffff0315bc01000000000017a9143b956676f8748666c71424b301a9a1d4554e0849870c9ac51400000000160014ff955c763d5c6d5092e121ee42e806490704ecfc400d03000000000017a914e441bf8eb1b00e1e99c07984aeb5d1b23b8c26cf870247304402206e1c1909a3cfff3f7f2ac82ebcb90fcdb3d9b07c8ed95d0a10478664f7d160c60220689aebf63dfc81d234298ad3ad8265f349039bffe243f9ec103f0821accf0228012102eea9ba79990ec589ce0c60d895ae5283f933e98b583872f0e3e90e795becb897b1870a00020000000001019d320941a891cd54eebb433eed3baaf09e0f06c0b283238cc5163e25a5939a6a0000000000fdffffff024cba0100000000001600141debbd78f6e6734ba3ad902df3781d8010ade747d0db06000000000017a9147b9a9e6d60400e5deb08c2be1a72a4afd411337e87024730440220307ddd38d20a7214177077d497424f77284c7846477b8882f26c82f928f7e4a00220643c16e67e1397749732076c03355f9b0ef1e4ef27e3953c986f439cff94ebb30121020a820f6114b3cdf4d761ca1f31aa2d9dd19ae4c7eea7e694709b9ac94a4455ccb1870a00010000000001019e3c5f66d7d0519b53491fd5184a8c962dbef84f5e28197959815c5fbedb8d4d3b00000000ffffffff32ee6a2e00000000001976a914c378ded906a60a72b6345b5eaff0d933427218a588ac7c0a180000000000160014cb60668f051c001353e14e4218806911879e934ef41d04000000000017a91453e13860d18555d9d2d595c8df33823a177d40ee87e72e16000000000017a91402de054ac7322088ff02f28d09f4e24653e870b7875d1f0500000000001976a9146b6c4f33d3931c52cc3760e0e864ac905b5aafb088ac902702000000000017a91403c04e312012941bbc2941e2a1c9e1db3f58e741876cd401000000000017a9144eb5ef7073cfa46e1dcbd432e5461169b69d87d18777de00000000000017a9148b219ff8975fdc4e92e99f2adc52396cf86d23b087e04e0000000000001976a9149a716a4e526dc3e1ff3d8fdb9513d21a584bb41f88ac7b670600000000001976a914e739159436dcac622b027fc8fe03266a940ec82188ac563001000000000017a9145e683f3531dc04fbfd40f77375e920d5d241a95487930a0100000000001976a9147762c98e0e3367094084716de9c539d489e6441788ac283a0900000000001976a91408f99e916e4cf152e6a241c05c79cedc0908486488ac747e06000000000017a914d3f1766bf4170e8491e522abc5f403c8c5b00cb387a25504000000000017a914af3ed025d98feaf94600c016bc71023edc305273871d2609000000000017a9147fc5ada0ec0d456d5c5b58fd21b7968bdd7a02df876efb5f000000000017a914e0e95aacb6866119226c2b391fbb8e165e1b9c87876bd00000000000001976a91451564fb5db5530ec7d6fa333647a01af7380d21788ac2f5cab000000000017a9149501fed908d5114cedd9386660873e62ca2f3dff8745da06000000000017a914b83032f7d5cca0051f788f1a2eff90ab2d79e3d48720cd0800000000001976a914eeb8bacc9220f59abb663e432985ee200d427f3088ace2580400000000001600144a12310c411a22a565621fa258e8426bd7c8d0b3e09304000000000017a914d5d8c6caf78fc21061fc4731c24b0c89a36c7ad687f82401000000000017a9148289e1a729717438ebcdf8c9e07596ec2d3acbaa8761610400000000001976a9146451b87e24ca86905eea9d851e28c5b8aa9dee3988aca4900200000000001976a914d37556e83e286f550870db5c825e6fffc312e55588ac8e3a000000000000160014353b138c3be7387ddc491c83e7159d736c537de1c4240100000000001976a914845c12e6aedc4cdbc79f2eacce9ca30d631b9aa788acb43f0100000000001976a9140e09830988a068eb6507dbae420639dd881b47c488aca0900200000000001976a9147e66edc27e301deb97e19ce70e4204ea670196e188ac473601000000000017a914168046f69a90adcf31e4ed4dd580b643894f3815879cda2b000000000016001423b91d13fd85c250078bef3e696141afbc7d67d7af5d0000000000001976a91481316d20a965c57e365ddbd88cf0b33df182497c88accadb00000000000017a91440aa6e55061da5ef2b270b375d169df7d578785a87805804000000000017a91471084b0c6799c2db9ad5ba2afd88af69cfaf38db87af5d5600000000001976a914fd61259381494884b2094a6c7e015ecf964dcedb88ac80580400000000001976a914d3e27eac3b18ab2fe0e543b0e24a457aba4508a788ac8b3a0000000000001600144bf26007bb626433beb32f46989c534c0ea36b94929204000000000017a914fec8bce62d0b8caf0881ce3596c1ca37d48df3ef87682a5d0000000000160014715f70274118762b58a11dcfbff636faa4be8a3d1c160100000000001976a914cac8f77da9673a862a29d6e24f9a0a3b4d6285d088ac436416000000000017a9144c79e8d15a93ef96ffe849ff1d013907a71f29cb8709340400000000001976a91493d66c36e24f6750c3b1f714d26ccc06e30f8c0c88acf4270200000000001976a914670d8e194515294a39ca836bcd89c5e63946ad7788ac37790100000000001976a914bd744f75e1051670b45ea769f2807ce42ffc376088acfa510000000000001976a914a2f869675fc607b7e32c21536b8882781057f3a788ac893d09000000000017a9140cbf435d9f011cf09c193a18c2c69c8c1319d5e0872ada07000000000017a91472b85f3d0b3091ffe3e1e33499bc850cb2e1bb628761390e00000000001976a9149fd915599b7f06b822f0296bd90abacd129f4f7688ac93fd16000000000017a9148f9ef19321ad0a62eeb1034ffc41303658095a91870248304502210089ca3893f1180326d1bbc27f89b23ce5e2ef4f35c9130eaff088f0484896c08f02205559db4a068aaa1547972e18ce77181de04206e8d2e2a4b2bfcff6a531cce199012102efd56b2aa9c332bafdadee106a21d3feea0e93e83b2c01e30172719b5e5a0e0b00000000020000000001019a8675f3a64ec4f2b6bf108d3bf00d3d0b332787b4a4a3a307af3d53fc4b2cfd0000000000ffffffff01c51a0a00000000001600146c18ac26595dd955b85b174a3d8c78e387071e8c0247304402203822f1f9b7908e8e80b3cb4a655cb80425feaa04319098af909d640bfc07e5a30220071eeed6e1f86a8fba49c6d29eeec5487bcf3c8d6833d0c181d41baa374ce950012102de8829afb19976f347b0f0b6fc27117abba6a336366aa16c0ffa6fc4a456afb60000000001000000000101e87926c591f6b4835afdc422aeeec569fd1fb35b1fadc16ec5c4042b3e181e2101000000232200201050f81f3cf192e8c5f1923700e7fa222aa2d4845303a4087f019408d972fd12ffffffff02843a17000000000017a914dfb610f26c86fbaab363c3b264bb283facabaa5887fe895a0d0000000017a914f02f35dfd649ccfdbb1e9a19156c3fb99a0d13ad8704004730440220077cd1a4eda2fd2251bb4e88fe9cb9abe73c40244c61916e54e19425ec38f43f02204c2ead8de4a7f7e537e2b71a0dd831d20d6f8fbfd0ad957221832f1a5ee884de014730440220187cc4f3f86a1fdb8dd9e688f85568bab932e4347fef9e1f052a8e68497808530220328c1918fec26d10a81d938bbb5f708eacd39884d57e60e0fa23ebad1c530e9301695221036414da3ee01031b225fff42f958db3f35064540a820a46dea3c5af79b1ef6a352102fae595ff8c0a41acbd2533e211a0236626b903472dab1c79cd3101c856d01faf2102c94ac1e83cd87f7566251b51112e20d79c69cc6d6bfcd5b3cbba3428b6ef2b8653aeb1870a0002000000000101a5b3a22222027d823b10ea60e917b4b5bd9e9d5edfa8f09126ea9305e2b7d7080000000017160014d8e7dfd2980abb8a17160af2eb778bed171f51a4feffffff01507d0500000000001600141d4f2ad2a9e6d7ddd83469425ff59441e4f9eb230247304402204c5b54e1026e7b8e424d10a1e7fe55c5268e27350beeb3195e3e92623ba1c14f02207448cca3450a71f5ca7cbbbf95e6022afdc964642f6f0bc8f0513677e8373eb90121021b1654ea4843ddfbf7c2c9bbdd0add4f81c1789b4531739c07bc169b7a523bc8b1870a00010000000001016381ce29bc6617456e1c212160df77cff54afb66d41634669ff5e57e2f59b2cc0100000000feffffff0204750000000000001976a9140f30034977561e424564ce8eca6554f721693f0688ac4226000000000000160014ce5bd11f4c403d73717538794d0d9c333c82585c02483045022100c8f748b7101f2ff35c4a80be66e31e131f19c889993e3b1980c4e87bf049b91e0220432099cdc708c333a1c8a79632b01762a7b10cbc2224d0f2f64ef896e7e98108012103d9ac44f61276f12807d3a66711d4a9b385fab4fd24e61b67de3610d5bbbc4d580000000001000000000101872a188b5c43f8990f99c10953cd72c9956ed89a9fef67b3424961cb99dcbd6313000000000000000002671700000000000017a914c1e70061f0c8d24dcf42b1dd3ee7749c841118ba87c32311020000000016001426da8ead36f9cb7232885e24bed55db638983b8302483045022100f2d38235d74912cfad18a1bbb834c29a330f15675b159157749a9c88d31816b602206a161222a42ede172d15c88141d812003dfdbe519108a94bcbbbe831a07e4b1001210330d24edc6c5646162672257ba2689297ecbc59c8005952f6aea51198df520d6c000000000100000001bb96ddbd2666d7c62f72f824bb6a8f8cee2d1a22c4b421afc9bb86e1b0bc27fe010000006b483045022100b3299607ff35cfbc2017b1841aa3d31c27f9135a008b949481357c013e061d560220748e3af715112ac5ac189a1328ede5b98f157ca6fd62d50f691a5c1b6698c4c20121031e9a636ef528970636cc811384ffde2a2c6d131a67d02e8e082b0c09c1669f5401000000020cdf0600000000001976a914b1da96c6d9f8ca1df601b6f0b375cca783a4de4288ac69acac02000000001976a9141e7c72c338f790b929422397218d8785a4aeda6188ac0000000002000000000103b8a6998b775445af1f3c24f80240b49106672ee41079f5e18ec0d636710dc47d9f0100001716001469c11bcdbf3462cf93c59b8005afcf0b524eabf0fdffffffb8a6998b775445af1f3c24f80240b49106672ee41079f5e18ec0d636710dc47d140b000017160014b016e01e92bf06c9be72807ac0fc4bc7019f7f30fdffffff9c4bb54d5060d1472adf4501099b49061beaaaffbca6da34dcc4532b4fadbfd32b00000017160014de89107b16de1d796cfedc3504dad23319499db9fdffffff0130ff2d000000000017a914cf3fd4edf20dc374e92523385f306553c0a43dd187024730440220531ce32754eb3f2a514e222d2f2cb831f07caba2f6ea6ca6ac5728f64b69ac4202204e20882cfe413982a6a04464487c7b7794f2f9bfd90743d18668378bc4be91f5012103abc33ddacdf49de4b23dd1129d09447ceb65c63d53fde522eda5ea02769548a9024730440220053eefd97e286c0c36713642f4845e19e4cdde2ef69dc598fe075c034b291cc702204149106ea978b851607830d937900c2c72a84b07244ae3341f12061139c190a801210210527396e491eadb17a4fb4a8c8f565c1479df2792ed9ac054e88deb8e263fb002473044022014ab0be12a8adf968e9a4491588cbc1d253be126a77c615a3d9fb6fd31de2d3e02207f03060c5fe44081d2b19ca6688e71e03d611bbfe516310cd711de5b3659b417012102c2faa9505090a725080ef731b099fd38b525b14c291c78dc9c15d8355bdc91a9b1870a00020000000001016f646bf26972b886246bd126ca3ce494fd8af18cc8f11b2a0c1eec9846061e45000000001716001480090cde8f2563879e0108a6b729178c4ff91d7afdffffff027da704000000000017a9143831317df36b605e41b860c0ac218542cd85808a87510e62650000000017a9141ba7a9a53c05d26a6983f216f4d1205634ac80fd8702473044022069ee012d64ed6d2af86a0cc318a419218717b9d4607fb6da3fd4233e7ef44b7e022002c769b0b9bd3d664849e73868d77efc4addbe1d41c242d901338a5e6b73a7b2012102dbc646d2d44ec390542a4abd6902c387afa9e4ce559b512343ed691fc481d8a1b1870a0001000000000102f9d6feea9503d67b39f794086cda7d5e68ffb686da541e9252b00575804b6a7a150000006b483045022100b0e1f5e48421310cc6ae7ab8aeb701ae2aa3529da7707355f3783ba7f83f10c002203305e035234f70d40a2d734520c10eaa96fa2e102f38bceb172a64fbf9291a94012102e68bd9ba1d05767adf0c3033c4a6466f815ad597e14ff85cfafc75570ffa1245ffffffff2451e3697747eb3a19ef65addf99fdb0a6b8b9c63da4af2f8ea147849433161f0000000000ffffffff025b1e00000000000016001410d60ff8a884cd7fd25248d0530bd5af1ddd68b9552a2a00000000001976a9141c17013569299a011183890111b8d49fb6038e3288ac00024730440220182c99a1329e72d102c1d82eb6cd09ac563e46384fdea9d7853294ccd7ac2ea902200db86458cc3e9e49904e5f35272015f7b4db7701fe892f38088b3547a0f837a1012102471061ab49123d49c68003fc6aa248d5653415400328ab52b0d1a63b6b13d88c00000000020000000001063c87469ed6acc80fe4dadc6e76ea3a12977d886f904b1d089ac2ea6f1798a64e0200000000fdffffff662e924fd382017253e8d3c391fcbb1d9866ebe42cba88bcc3b026556ee14a820000000000fdffffffb5be33c0ec146f30403b5d17e1e900841a14131d0007e7bd9035d69f214f84820100000000fdffffffe5cf501b9ca4b082fb046aa98df4e804776d3ca31291b2504f5e8a1bdb79dabe0000000000fdffffffbe54fc937a033713aa31eefdb9ea9f2aef3e0a1e3e6e10637ded03bc417abace0100000000fdffffff026b83c781488ce17704306f1d64e3a666f6a83e936023532f7be75aa555dcdb0100000000fdffffff01977f2f00000000001976a914561c8f5dcb731ccb9af98393fa0e2dbfbefd7aee88ac0247304402200a7201ccebb8eae607f01f1e73dc43022881c8fa4505e5cf7d068dba2d9f10d302206084c24192f6ddbd04b00be4d7addc5d5a6ea2fe3a4734bb3bd021017e4015b80121037bdada249cff349769d9ea6d2efe5d76d1e3beddac5429d735fbe7f6553edcd90247304402200e6adcc67185f0f8c12ab99eadd6f36a32f187911af084bd021a6240156ce68f02202d461ea2bc4509145cc11c6f69ab2db67106818b132288be637ca211d6ff024801210373e81d5ad095408ff305fcc7c2c14c81e6fa962c50fe3ffa1bdc41e1890b17f20247304402202db1cc195f387ff5dbd4a79fbaeb8e7dd7a4990a3d4c47ad981ca6f3f3768391022068d94d5f29552765be2e311ddf6761e54f378f9414602b913f7c56076faecf2c012103cd29ef645c1948fcb04cec63e7a45ccbc8b65497616978b6ea8ae13fe4687bf70247304402201dbc1edb23acc6adcf6e631822d4abd4f797055bce1e65cbcc428f75757b853202201f958da9d493f2ab806d58fdd68e8f6c29274d29d0b8ebe72d73acf52ab986db01210273e4e29485a8da1af6695d4139d256b79e58aec75e75c77143f5241018ae821d0247304402200760498a6bb830bb8ae89db766df42e9ac64728687f9e91bcacb77af0fe5d06a02206a808a0c60b894677a149f99ffad087aa1b9f17fe238c11ddbbf6b1a6fb9a3410121033461ad224af04730d6fdfabca98252076c3ae3806fca31caa878f08458aa38cc02473044022004803fb767a77e55bb5d7911f43b890ce63173a20c8083927cba1c63e624d406022054dfed5ae4b5aba3cc46da6f3d1a066ff336d252e54742f85f44d96b24243f01012102063a9e0afe23cc732864101599f8d07be84228f89f838bff29494075f02f39dab1870a000100000000010190d17c5ec983685ae455910a8588a68c49b3c9792f986a68c9e9b64e6d1d32d902000000232200204c17874906b9b484cebc0fde0e7c44705050792b90492bafb7d7f732812d3ce2ffffffff02404b4c00000000001976a914a250d351fd042f41ab739574b9a2d0578ab624bf88ac07eb56080000000017a914a2ac5855a64ba9fe3d808114146e1b440c4b3525870400483045022100c0c650cc00bcc79d1f9fcfed118601c51682df4a17981afa6668adfc9804af7802204db5bef84360e19c97abcb2979d866766d5bb7c64a2801994b6b23c8434e4e770147304402204faa619c7fb1cc4838ed885793cb8f7cbd9520aca90f80047e28ef2214dd2ec3022074dd4fab67a11ce003e92aad6c5daeb2ca52e0d5c81c8a85106479cc205dcda20169522102f86574bbff94767438fd14e8c27e4f074200b351f520cf44cbb182843a3a8d6121033df348ef562e41a2a38c3fc1ccd38a3184c04671f0dd9dd83cb8f0e03ec2708e2102670a229788bd59d537b0379739daeeffaf9fcfe7c411fc8cb785a0a586664fdf53aeb1870a000100000001e9860bc1c053e376100a92db44dd0eb3d6241b851955ee2db514894ef3cf51c3020000006a47304402200fadb0b7d19d0aca703a203ba612c3ca72fae86e863947ad7d6ea5cc628050a302204a1a3ee196b09e63ed6201af722d213b8bcdf3b2d935a6610450524bd72d1e8d012102936c15394948d03a7ba3d4a7e7c7523e14194b3ab808cfe5baed526e15bc0651ffffffff0210a64709000000001976a914c8a6bc95dfec3fa60785b300278d5378c6d453a088acf9de16000000000016001419dfb6e485d667649eb9027c577fc051dae71f0b0000000001000000000101bcc3cdb83fd60ac062fb15f3c8d9852d39fb28a6575b68314f1598d96a58c625010000002322002028cdcdad4c4a07bb6ec5925f2196c4e293898127650b3044fbdb6bab317a7099ffffffff02cb7c0600000000001976a914178412a75e907720a886591d008f10f9f3466f5188acecaf57200000000017a914ba695f1c0d90e1b0fbcc0f1f4623b815848a51f287040047304402205797dac01c67c55dc766706c6cd8f5a26a30dc98bf05f2363acb9b9bcbbf317f022018c7e041a3a8b1f1b54a348fabaf6109a4f3d1a5f58f2ed55ac98ba372ede53201483045022100b6a487645eb046b8dc028a7cfe758bbb03dea784655edeb443afe89cb61d14c70220655df45427eea9387e776b8ad7fe848fd9c215de8269f0348d381c4a0b1251170147522102ce06807bdaf64c3f40d3e4fe990910c82e8b8c3ac8df0c3cf373fa72823f958321039332e240be260cc87f6b1bae52aac5e37fcd61dd89849a8113f14d977e5f39dd52ae000000000200000000010125059190c84b24749e2558c92f0fe049369f07a6ffc5e4f72d9718aaeaf31a7f0100000000ffffffff02fb420200000000001600144e11f3feec543860df274eeab67012608ba939964b490200000000001976a914ec03ec56b76c9398626fd14e17ea23c5e6ee018888ac02483045022100a06e32275e2398421c06b8a2e05716435dfd3d0338115c0121f17611f9cae15102200c7e7429ce64879c9a668d600185b8692aba933b3af2cb0d1bb645268452253b012102bdf3289ab542598c6cbb9d5fe8f07fe31da4495203061a11c9add18b57cf0c4b00000000010000000188273ebd36c7147382027c43325fb618a6192a5a5e10e25072e3c19e696ebb86010000006b483045022100f08866af42bd3b4cde4e0322aef9905e7e91b6f2fd6f74e07f98c4650c9449f502202419439695dfbaf00a43788de8ba6db011d19022f3c0f07dcbf7f712aa70cb42012103f9d3a6ee01d462dcd9e9833150169001afceb41c1076e08a2f435b59f8b1261affffffff02a7ff2200000000001976a9144a58af826227a82b45bd48a69c0618e5f1de0d4688acdbc30100000000001600145a4f089fe01c25c865b23ee7eacd0ca7cf76e5e7000000000200000001b1410d3e8d263ff4a268b53e2e722946e4260b2fa0cec06a8fa402a9ea22e7c5010000006a47304402204782f4a1a2ebc065ed1ff361784f2ea79242bf3f1c9720317754478041a734af02202bcd541b4e7b6b232a6b62a1b8679508b1e27e5e4f697b7f9a5d5fbf18a76387012102b1822ad675522904b61ac135b8a9d36e9b28a1c13b6e54e7e281e746d4d0bb73ffffffff026fd62d000000000017a9140e9259a0faf3c56342caeeec43d61e2184a1144a87884e3a01000000001976a9148b41c041d8dadc41d3efd8b0d430ac80274377ec88ac000000000100000000010506ebe3e53c05518abb9e265e104daab7271f9bd2283d655dc56108eb41eddb5f000000006b483045022100cb23733b6e14b9ef5381db429cc02bd7dcecb2ec620981f17e3cf9d007852d240220090f16b37f50daccd81cbd4b1a154263f9100ecdb76a7ead967f26d280ae9c1f012103da3e84d6d636f2022282db92433773f703d2fb738fe59a5d77da5adc3e2c7e1dffffffff73c175c9f8f657672be8061e079ba63efa89437b1fb693855e881a7964fd7e25000000006a47304402204d6c6a89b44588f1fc2d77f01217eafa122d4c5487e62026a7a5d56f1d1ca119022002239b5f2cccf82f2bf0b7c8621020bc499757dcd14b126906503599c425a3a301210387114296e1c4edadc0c47482b0961e8c9ca37ea256d097c2b49583f19ac59856ffffffffb17008dfed5fc8a91c031cc99ab30c321be4cb33d273c6c6e56b9daa38125c7b0000000000ffffffffb448c7e822385d22f46dec833ae53f83cd3ec3cd0b0f5b77973bd101d788896b0000000000ffffffff3153e6912d9b669f2c58d974b44585752ae7f6b001470a4cc40f2a0d06509f6a0000000000ffffffff01a48779000000000016001436552a1c649baccfee51d6bffb1951e3685ed692000002473044022041bf6e490c22f9b2e817322257e269d712896091414ea5444098815ec8537fdd0220280101a6b811d57b79258b36f69bf4b16bfec35b96d75ce80f83de872884678601210363e40bd07d4ef8b06aedc340b7a0ad588d5bee7234b74a69313872cba2d0dc2902483045022100933da4eed06a472c7a8911b9885ed1e25675c7f6dbfdcddc8a2be437184dade502202a40b5b2a5f6a647d01b8f9177f89132947b39e0ec7f4d60bd1ad1ec504d22f3012103093f9569270b106f0b41cf96e56363ef093b90d1c97da552322f7e67bac7f151024730440220097003a8faeba34e9118b16920390ab2748970ee14c8ba484e691173330eea5f02201ca72e92ebf06541d91499b81b8f4f5a322997f610e06c16cf0eecf04c621cf9012102f8857de858c14dc3836b026ab88b6038f5716f923275d40fe7207e43c687bc60000000000100000001981c89d9e62bdfc5918094ad88ffe9bfa272ddf8f796a5d189874df57c1ec07c000000008b483045022100ba0fd24606b8c9480d28478b40486dbc0c830ac11ad6f56cdaaf3273026f02ab02202c1e0673a2dd7be785425c83bed148890db59d51377eb124e4beba068b239c8e0141048454d039fb7bde4e32c0fccd96dac9a7de33879666ee3ed2e9c88971ce4ed9e37b2828d634789b222c053f6547e6ecdf4869201e74f72267f48f297b7b644339ffffffff01a4ee0700000000001976a914c248b989aae8d90a6242da04f19fa912dc6e8f1088ac00000000020000000001034afd8a48de844106fffb892e53d6269a84b72e0a00c1e94b7175ab0bac46902a0c0000006a47304402204378a0385b713cb38224082a571a195f44680607480be725a7caa7c2ae74883e022002f72e9c716fe958f0346270c7225fba8ed5c6e5e5e4fccd9d0b18c5aed34a71012102a3576bc2466fb6233dadf3df9ce7c92f93965b56b2b1de17ecd933de21eb16b0ffffffffdee1f0b61569b67d592a66c27f53b4164b08bfeefb46b1bb7cdad9a4f65ecb49000000006a47304402200cb20f9b6e76cc4c37dc4ce8899e556726dd475e5115e381b8a980ad0a95eb58022078e5af79d0bd41ce07568eba335123dd17c1f1aae8d0c87377368ad4cb7e0d09012102a3576bc2466fb6233dadf3df9ce7c92f93965b56b2b1de17ecd933de21eb16b0ffffffffada8e51e20fa6b9dd10e95cfc36d2fa3523cfef06bd230d247f3bd47c97d54550100000000ffffffff02a800360000000000160014de83d2189cedab4d984ab78488f00dfdf5e3287015a80e0000000000160014ea01e04aaafa8255b47ede6648e7a0c111431bca0000024730440220673f1e40d5977a114633e8822c520bd0b0d96a83e0b0378a26de89ede6c15d1102201a0989d550e84cfa342e5bd8ed28b364e0c4702c1f271245bb3277b6ae204e5d012102b648eb3b32f72dc612c0412db37bba2ac30c44014e7a7581f52ce54e4d67b9d800000000020000000270867509979084a1d4b7d68f98da815d0ea4bcb0ad6908d0d26bbae80814af76000000006a473044022048966d6c364ec2cbac56965426a62ad8ff0055fbdaef9114da883b9f99baeb300220484dc01e8f5d71d33b8e6d09c5c5a4051a8ca0613e1dd41318e9a1eec955a6ae012102537169a50154c653f1f9799cfda9ea4440108225370cb3db520a0e260ef4ef03ffffffffb4d85fc9249012ac332342c0c1a0d3861c988bf7c7de7de8924a54d486c0e779000000006a473044022001f390a3895940a9c777c0190c0f54716c2bfbd6a278458b7bbbab1e9a974b1a022001d553243f0f025ed609fa2519015682b8c4fe8167cfc5eb2ff34e107ea38708012102537169a50154c653f1f9799cfda9ea4440108225370cb3db520a0e260ef4ef03ffffffff027cd92700000000001976a9148bfc0653d121bf6367c9b78f0f12c3a6880bf16688ac700a3000000000001976a914205826a3fb33a0fcd8c8e177247b48877508260f88ac0000000002000000000102e6a34cbbd1f88e0ea32e013d0e19a150574b2963eeaf221fdca1ea9673686f870100000000ffffffff9ca7b679eb638ed3e3dca3855f2a761b4296a0471ecac3c769d64bdd4e54e3070100000000ffffffff02a7931400000000001600147eef9a2c606f75f7ee5995b6b5a65ee512e08451e3380c000000000016001459f627e531193db7f3a525ae32df9eb45370328402483045022100c99a034876bab21f203f6a8c0f7de3c43ab2aea76e8a2747c39dc9440eb42882022007a636ac3e8f822c9843e8ab2a03792657dfb01703009b016cd778ecd50bf9590121022ee959f516a8d466b32e0a856411a389ea452c8a3b82b12f2f648aba82e00562024830450221009b718162daff3ee7e235371b022d23d0592ab019671bbc7d3cf172a72a8479860220745e9050835eff30c3d7d70cddc84632819d110a3a6a245abd42b9bae23bba18012102cc4a45037362de7a630870382f1fee915a1dfcaa0d1738dc9b503eb7726504b4000000000200000000010152caade841641f3e524811e1608665cb73b7ac25f3a6c0211099c527de9ef3bf0100000000ffffffff021eea00000000000017a91469ab330f75fd4cc065a2151a3fc7676fefb8a75b87157c040000000000160014c4485c0c4bf12c3eba18a86c35611662f9216d6302473044022020c878f15145a3c407126a712862a19e8d0c6066ae26edb100dd8f2ac410bdfe022034d547cc3e9fc059b4c4ca52cca2a6a4c44c34d563abdda59738dbdae08950e6012102b86fbb247c7a6ae45aac84f5633b59ba2a09a3dd09d0fe239d36e202671049640000000001000000000105d8408fe9e041895ce84841973e6ac8e409e19609fe9a8046c0832ed80de0fa0c1000000000ffffffff823ce480f39394b57dfebbc460885f6cc71e7a7f5fd3029968bcde1a13c3e6680100000000ffffffff336c4529efcf90081564b918367726e2017356f14a8ca3cd728ddee1c541488f0000000000ffffffff63b40591ea0521a641e20612fadd2e754531b4358652b86e7b155a539915e9a80000000000ffffffffaff699e5b7c959904b5622340c0dfc905d93dce50e7de670eaa6042b7c5c36d43b00000000ffffffff0540420f00000000001600142ff099afd4dbc6506ad488760a39574d521e51b840420f0000000000160014ce6fcea06b82087b16a78a8372b3c6b3a961e76440420f0000000000160014db151b79d83e1864c0c3d5541d45ef9f2c4d219340420f0000000000160014f05fa715a390cea1736a7b2a0259c23c3d77c4c040420f0000000000160014f18aed18bce9d56deb56115cd351fbe9990a7a5a0247304402201147a76e63ed59be3cf36ca41f0a6820a54b36b05ac7fa0754bc73f584f80fce022073bc8f2af98b17abdf25add10bb518201b99398940f86a769760c011f1e4d5c30121028660ea442a740bc31c79c1b4edbde91c0ccda97fe43a8f32c4116daacbce632d02483045022100e3a3598e60387c3494fbf2e554ccd66d7535ba3f5f611c2cf94e5d76d318e77102207987a0d22c313bf95eade88e076d4a4a9d180aeb160917024426ad2502855077012102899f0e9705052e458e67339e9812535f648fdc55242fdd43fa9474387745f44802483045022100ae8235cfa4affd0a3c27b9ea2aef31eb6155ad8362b6ec2708299a6e4f3ea60202203d1f2d2cc993be5a199df912982d72263a632c18bfc69d00a09406acb1ba67470121023f578ac20dfb94d1ccb0d067f4e2f610006ac2ceeaec39f74fcaa0cb515cef4602473044022064a248d9b84e327eaae7dfb7394281807d813b52f955384684842f523462024c0220544fe4345f8ae496ae26cff6eaaac607fa6495156460ec4820f41fafe6d08f87012103b61a1d01ca68ad214724ee0df5d96b201faf16dc3abc02346d51c6c097211cab02483045022100a40cb59269085e50bd95c4d83a814cdaa9d0923dfbbbebfa3ddace33e567a9ab02205aa027d73e5896b125ce43943a45823710f43402f0a998cee9ca3486945197c20121037175a85efd47494b868919a5cd31e909fd5b3be180c1117be5ebe7b2afabbcaa00000000" + btcblock: + - getblock: + req: + - + method: getblock + params: + - "0000000000000000000a276fc7641724fe5ad132f598c96eff403958e76667e2" + - 1 + res: + - + result: *btcBlock_segwit_txHashes + btcblockWithTx: + - getblock: + req: + - + method: getblock + params: + - "0000000000000000000a276fc7641724fe5ad132f598c96eff403958e76667e2" + - 2 + res: + - + result: *btc_full_segwit_block + getrawtransaction: config: proof: 'none' From 6c1b4bfc2c84a8304ee8bc0c9bcc9e323528c414 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20K=C3=BCchler?= Date: Thu, 8 Jul 2021 12:13:38 +0200 Subject: [PATCH 004/101] added btc-segwit tx --- c/src/verifier/btc/testCases.yml | 86 +++++++++++++++++++++++++++++++- 1 file changed, 85 insertions(+), 1 deletion(-) diff --git a/c/src/verifier/btc/testCases.yml b/c/src/verifier/btc/testCases.yml index 933b78be5..ab3ba6c5c 100644 --- a/c/src/verifier/btc/testCases.yml +++ b/c/src/verifier/btc/testCases.yml @@ -256,6 +256,56 @@ btc_full_tx: &btc_full_tx time: 1591782412 blocktime: 1591782412 +btc_segwit_tx: &btc_segwit_tx + txid: 754f3816c6d4d0729e00939c39441a55223463570ddbe455b783f0bfd61d8c45 + hash: 8a13f29f43401ca9f9b7c6369ae33a023b2f14fbb26633d86864eddf091bb86f + version: 2 + size: 223 + vsize: 141 + weight: 562 + locktime: 0 + vin: + - txid: 181ad955a662d8efd47cd2fb07c191043452b71b0418543e36cbab1b44a32944 + vout: 0 + scriptSig: + asm: '' + hex: '' + txinwitness: + - >- + 3045022100ad54ac2f0c0867432ad08efee0ac63a9a5f1f9c7fa6e19c41f82be5fdeadf3ba0220780caf96eef2db4c0a302764da3e53c120c4238dde25e4cb1a7eec9fde7d8c0a01 + - 02a1cde3dfe8d92f8ae2626c5548dd039c95cdb6605071168527a5a052e037e634 + sequence: 4294967293 + vout: + - value: 0.00227671 + 'n': 0 + scriptPubKey: + asm: 0 583f0afea3c306744856572107c5a80e6ca141b1 + hex: 0014583f0afea3c306744856572107c5a80e6ca141b1 + reqSigs: 1 + type: witness_v0_keyhash + addresses: + - bc1qtqls4l4rcvr8gjzk2uss03dgpek2zsd3qujhsy + - value: 0.02720963 + 'n': 1 + scriptPubKey: + asm: 0 64b3b903602a28bacb8f6d914bfce514e7062341 + hex: 001464b3b903602a28bacb8f6d914bfce514e7062341 + reqSigs: 1 + type: witness_v0_keyhash + addresses: + - bc1qvjemjqmq9g5t4ju0dkg5hl89znnsvg6p05alx5 + hex: >- + 020000000001014429a3441babcb363e5418041bb752340491c107fbd27cd4efd862a655d91a180000000000fdffffff025779030000000000160014583f0afea3c306744856572107c5a80e6ca141b1c38429000000000016001464b3b903602a28bacb8f6d914bfce514e706234102483045022100ad54ac2f0c0867432ad08efee0ac63a9a5f1f9c7fa6e19c41f82be5fdeadf3ba0220780caf96eef2db4c0a302764da3e53c120c4238dde25e4cb1a7eec9fde7d8c0a012102a1cde3dfe8d92f8ae2626c5548dd039c95cdb6605071168527a5a052e037e63400000000 + blockhash: 00000000000000000013762fa6702583f502222adfdf24a738dc5bc758fee793 + confirmations: 3 + time: 1625736960 + blocktime: 1625736960 + + + + + + btcBlock_segwit_txHashes: &btcBlock_segwit_txHashes hash: 0000000000000000000a276fc7641724fe5ad132f598c96eff403958e76667e2 confirmations: 37 @@ -2410,6 +2460,7 @@ btc: result: *btc_full_segwit_block getrawtransaction: + - config: proof: 'none' input: @@ -2442,7 +2493,40 @@ btc: res: - result: *btc_full_tx - + - + config: + proof: 'none' + input: + - "754f3816c6d4d0729e00939c39441a55223463570ddbe455b783f0bfd61d8c45" + expected_output: + options: + bytes: "020000000001014429a3441babcb363e5418041bb752340491c107fbd27cd4efd862a655d91a180000000000fdffffff025779030000000000160014583f0afea3c306744856572107c5a80e6ca141b1c38429000000000016001464b3b903602a28bacb8f6d914bfce514e706234102483045022100ad54ac2f0c0867432ad08efee0ac63a9a5f1f9c7fa6e19c41f82be5fdeadf3ba0220780caf96eef2db4c0a302764da3e53c120c4238dde25e4cb1a7eec9fde7d8c0a012102a1cde3dfe8d92f8ae2626c5548dd039c95cdb6605071168527a5a052e037e63400000000" + btctransaction: *btc_segwit_tx + mockedResponses: + options: + bytes: + - getrawtransaction: + req: + - + method: "getrawtransaction" + params: + - "754f3816c6d4d0729e00939c39441a55223463570ddbe455b783f0bfd61d8c45" + - 0 + res: + - + result: "020000000001014429a3441babcb363e5418041bb752340491c107fbd27cd4efd862a655d91a180000000000fdffffff025779030000000000160014583f0afea3c306744856572107c5a80e6ca141b1c38429000000000016001464b3b903602a28bacb8f6d914bfce514e706234102483045022100ad54ac2f0c0867432ad08efee0ac63a9a5f1f9c7fa6e19c41f82be5fdeadf3ba0220780caf96eef2db4c0a302764da3e53c120c4238dde25e4cb1a7eec9fde7d8c0a012102a1cde3dfe8d92f8ae2626c5548dd039c95cdb6605071168527a5a052e037e63400000000" + btctransaction: + - getrawtransaction: + req: + - + method: "getrawtransaction" + params: + - "754f3816c6d4d0729e00939c39441a55223463570ddbe455b783f0bfd61d8c45" + - 1 + res: + - + result: *btc_segwit_tx + getblockcount: config: proof: 'none' From db436dd4a6ea211a00b9b7521350e365cb57a5ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20K=C3=BCchler?= Date: Thu, 8 Jul 2021 15:22:07 +0200 Subject: [PATCH 005/101] added zksync --- c/src/pay/zksync/testCases.yml | 166 ++++++++++++++++++++++++++++++- c/src/verifier/btc/testCases.yml | 2 + 2 files changed, 167 insertions(+), 1 deletion(-) diff --git a/c/src/pay/zksync/testCases.yml b/c/src/pay/zksync/testCases.yml index 7b30a7f22..84aaeae0a 100644 --- a/c/src/pay/zksync/testCases.yml +++ b/c/src/pay/zksync/testCases.yml @@ -129,6 +129,7 @@ tokens: &tokens zksync: zksync_set_key: + - config: proof: 'none' experimental: true @@ -176,7 +177,6 @@ zksync: mintedNfts: {} pubKeyHash: 'sync:0000000000000000000000000000000000000000' address: '0x8d33caff9b73a3eb24c83ac79bb5ed56126f284c' - - tokens: req: - @@ -234,6 +234,170 @@ zksync: res: - result: "sync-tx:4f8b59a5d7d4f128c3024b481eebc66de41428636c385ca68f00ea5f0d785564" + - + extra: "with multisig" + config: + proof: 'none' + experimental: true + pk: "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" + rpc: "https://rinkeby-light.eth.linkpool.io" + zksync: + provider_url: "https://rinkeby-api.zksync.io/jsrpc" + account: "0x448d2286d9d6996241ff1f87bd2e24692975cabd" + sync_key: "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" + musig_pub_keys: "0x5303a0015f8d5a8fef6cb1d60a034ef28dc4ac6aefa33c936d5aa0927f7c169a4a646591170aee46931ade1148038c4c75c3972af2281a580756a0317c19872d" + musig_urls: + - "" + - "https://approver.incubed.net" + create2: + creator: "0xaa8c54c65c14f132804f0809bdbef19970673709" + saltarg: "0x3bf6b1cbce10cee9cba978f4f2466ccaf1802af73f15a0f1dd8bff9e666bf2d8" + codehash: "0x96657bf6bdcbffce06518530907d2d729e4659ad3bc7b5cc1f5c5567d964272c" + create_proof_method: "zk_wallet_create_signatures" + wallets: + - + type: "l2" + address: "0x448d2286d9d6996241ff1f87bd2e24692975cabd" + threshold: 1 + signer: "0x5303a0015f8d5a8fef6cb1d60a034ef28dc4ac6aefa33c936d5aa0927f7c169a" + owners: + - + roles: 6 + address: "0x8d33caff9b73a3eb24c83ac79bb5ed56126f284c" + - + roles: 4 + address: "0x082977959d0c5a1ba627720ac753ec2adb5bd7d0" + input: + - "ETH" + expected_output: "sync:ec0de4692863fc7b1459cb98c6be56ada438d991" + mockedResponses: + - eth_chainId: + req: + - + method: "eth_chainId" + params: [] + res: + - + result: "0x4" + - account_info: + req: + - + method: "account_info" + params: + - "0x448d2286d9d6996241ff1f87bd2e24692975cabd" + res: + - + jsonrpc: '2.0' + id: 1 + result: + depositing: + balances: {} + committed: + nonce: 0 + balances: + ETH: '100000000000000000' + nfts: {} + mintedNfts: {} + pubKeyHash: 'sync:0000000000000000000000000000000000000000' + id: 167081 + verified: + nonce: 0 + balances: + ETH: "100000000000000000" + nfts: {} + mintedNfts: {} + pubKeyHash: 'sync:0000000000000000000000000000000000000000' + address: '0x448d2286d9d6996241ff1f87bd2e24692975cabd' + - tokens: + req: + - + method: "tokens" + params: [] + res: + - + result: *tokens + - get_tx_fee: + req: + - + method: "get_tx_fee" + params: + - + ChangePubKey: + onchainPubkeyAuth: true + - "0x448d2286d9d6996241ff1f87bd2e24692975cabd" + - "ETH" + res: + - + result: + zkpFee: 33120446126802 + totalFee: 43000000000000 + gasTxAmount: 7600 + gasPriceWei: 1000000000 + gasFee: 9880000000000 + feeType: + ChangePubKey: + onchainPubkeyAuth: true + - tx_submit: + req: + - + method: "tx_submit" + params: + - + nonce: 0 + fee: "64600000000000" + validUntil: 4294967295 + type: "ChangePubKey" + ethAuthData: + type: "ECDSA" + ethSignature: "0x2b281880b7c73127570aaa4696ea6024f826977649d15fc37e422ffc996121153a909302fad27e4548c66c7e0520b6f77c5027c88104b38fe82af16b85d4c7061b" + accountId: 167067 + signature: + pubKey: "1604e29d6544afa77334fce3964f68b01cdedbbdaf739355311195fd25292f04" + signature: "c936c89a624dc5effbb54bd3b2a2d56f4deac9103051d4607476770c3451d321784751218821e73f2f4d514068cd2bfd511bc4137fa28bdb660682944a754001" + validFrom: 0 + account: "0x8d33caff9b73a3eb24c83ac79bb5ed56126f284c" + feeToken: 0 + feeTokenId: 0 + newPkHash: "sync:ec0de4692863fc7b1459cb98c6be56ada438d991" + - null + - false + res: + - + result: "sync-tx:4f8b59a5d7d4f128c3024b481eebc66de41428636c385ca68f00ea5f0d785564" + - zk_sign: + req: + - + method: "zk_sign" + params: + - + message: "0x0700028ca9448d2286d9d6996241ff1f87bd2e24692975cabde9d10277efa866916138305467cfca1858b5b3f6000035cb00000000000000000000000000000000ffffffff" + proof: + - "0xd693cf7edf35ae80a6117fddace9faf23c23b66f4ff925d0312f32a7da7585ea321cd6fd7ae0e7a81029422d6b1dc0c26cf1bcf626d9adb412555eedfee0c3d21c" + pub_keys: "0x5303a0015f8d5a8fef6cb1d60a034ef28dc4ac6aefa33c936d5aa0927f7c169a4a646591170aee46931ade1148038c4c75c3972af2281a580756a0317c19872d" + pre_commitment: "0x7f5588233f6d50792a05146fc73260c7b336baa27364d07ca4460a68c8118b390000000000000000000000000000000000000000000000000000000000000000" + account: "0x448d2286d9d6996241ff1f87bd2e24692975cabd" + - + method: "zk_sign" + params: + - + account: "0x448d2286d9d6996241ff1f87bd2e24692975cabd" + commitment: "0x9bf75261a1372a9694d3e8764e62a8ddb747eca5219d2f8447b0a81d48d30010a9bd94d7d2fc244fe993a1dae294d08774da17b7588481aae34facdca327e288" + message: "0x0700028ca9448d2286d9d6996241ff1f87bd2e24692975cabde9d10277efa866916138305467cfca1858b5b3f6000035cb00000000000000000000000000000000ffffffff" + proof: + - "0xd693cf7edf35ae80a6117fddace9faf23c23b66f4ff925d0312f32a7da7585ea321cd6fd7ae0e7a81029422d6b1dc0c26cf1bcf626d9adb412555eedfee0c3d21c" + pub_keys: "0x5303a0015f8d5a8fef6cb1d60a034ef28dc4ac6aefa33c936d5aa0927f7c169a4a646591170aee46931ade1148038c4c75c3972af2281a580756a0317c19872d" + sig: "0x050394325427a033c78a314340be3b22f843bf110f67dfa1a48668512be66d610000000000000000000000000000000000000000000000000000000000000000" + pre_commitment: "0x7f5588233f6d50792a05146fc73260c7b336baa27364d07ca4460a68c8118b39b46c017ea874fad0b07e87bf227099e916ba4d355730c2de5830162623127d49" + res: + - + result: + commitment: "0x0000000000000000000000000000000000000000000000000000000000000000a9bd94d7d2fc244fe993a1dae294d08774da17b7588481aae34facdca327e288" + pre_commitment: "0x7f5588233f6d50792a05146fc73260c7b336baa27364d07ca4460a68c8118b39b46c017ea874fad0b07e87bf227099e916ba4d355730c2de5830162623127d49" + - + result: + sig: "0x050394325427a033c78a314340be3b22f843bf110f67dfa1a48668512be66d61042517e6807360fab026dab1979ca27a2e1f80a8eacf178f8504283fa46dd025" + pre_commitment: "0x7f5588233f6d50792a05146fc73260c7b336baa27364d07ca4460a68c8118b39b46c017ea874fad0b07e87bf227099e916ba4d355730c2de5830162623127d49" + commitment: "0x9bf75261a1372a9694d3e8764e62a8ddb747eca5219d2f8447b0a81d48d30010a9bd94d7d2fc244fe993a1dae294d08774da17b7588481aae34facdca327e288" zksync_transfer: config: diff --git a/c/src/verifier/btc/testCases.yml b/c/src/verifier/btc/testCases.yml index ab3ba6c5c..dccb85459 100644 --- a/c/src/verifier/btc/testCases.yml +++ b/c/src/verifier/btc/testCases.yml @@ -2416,6 +2416,7 @@ btc: - config: proof: 'none' + extra: "with Segwit" input: - "0000000000000000000a276fc7641724fe5ad132f598c96eff403958e76667e2" expected_output: @@ -2496,6 +2497,7 @@ btc: - config: proof: 'none' + extra: "with Segwit" input: - "754f3816c6d4d0729e00939c39441a55223463570ddbe455b783f0bfd61d8c45" expected_output: From 4e58bac5aa37d17560c68463b673a83b26612f02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20K=C3=BCchler?= Date: Tue, 13 Jul 2021 10:06:05 +0200 Subject: [PATCH 006/101] privatekeys as arrays --- c/src/api/eth1/testCases.yml | 12 +- c/src/pay/zksync/testCases.yml | 350 +++++++++++------------- c/src/signer/pk-signer/rpc.yml | 19 +- c/src/signer/pk-signer/testCases.yml | 3 +- c/src/verifier/eth1/basic/testCases.yml | 9 +- 5 files changed, 187 insertions(+), 206 deletions(-) diff --git a/c/src/api/eth1/testCases.yml b/c/src/api/eth1/testCases.yml index 0fe700bea..4ebca0d96 100644 --- a/c/src/api/eth1/testCases.yml +++ b/c/src/api/eth1/testCases.yml @@ -95,7 +95,8 @@ account: in3_signTx: config: proof: "none" - pk: "0xe20eb92b34a3c5bd2ef0802a4bc443a90e73fc4a0edc4781446d7b22a44cc5d8" + pk: + - "0xe20eb92b34a3c5bd2ef0802a4bc443a90e73fc4a0edc4781446d7b22a44cc5d8" input: - "0xe480808252089463f666a23cbd135a91187499b5cc51d589c302a085010000000080018080" - "0x8A91DC2D28b689474298D91899f0c1baF62cB85b" @@ -104,7 +105,8 @@ account: in3_signData: config: proof: "none" - pk: "0xe20eb92b34a3c5bd2ef0802a4bc443a90e73fc4a0edc4781446d7b22a44cc5d8" + pk: + - "0xe20eb92b34a3c5bd2ef0802a4bc443a90e73fc4a0edc4781446d7b22a44cc5d8" input: - "0x0102030405060708090a0b0c0d0e0f" - "0xa8b8759ec8b59d7c13ef3630e8530f47ddb47eba12f00f9024d3d48247b62852" @@ -140,7 +142,8 @@ account: eth_sign: config: proof: "none" - pk: "0xe20eb92b34a3c5bd2ef0802a4bc443a90e73fc4a0edc4781446d7b22a44cc5d8" + pk: + - "0xe20eb92b34a3c5bd2ef0802a4bc443a90e73fc4a0edc4781446d7b22a44cc5d8" input: - "0x8A91DC2D28b689474298D91899f0c1baF62cB85b" - "0xdeadbeaf" @@ -149,7 +152,8 @@ account: eth_signTransaction: config: proof: 'none' - pk: "0x4d5db4107d237df6a3d58ee5f70ae63d73d7658d4026f2eefd2f204c81682cb7" + pk: + - "0x4d5db4107d237df6a3d58ee5f70ae63d73d7658d4026f2eefd2f204c81682cb7" chainId: 'goerli' input: - diff --git a/c/src/pay/zksync/testCases.yml b/c/src/pay/zksync/testCases.yml index 84aaeae0a..d88217403 100644 --- a/c/src/pay/zksync/testCases.yml +++ b/c/src/pay/zksync/testCases.yml @@ -133,7 +133,8 @@ zksync: config: proof: 'none' experimental: true - pk: "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" + pk: + - "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" rpc: "https://rinkeby-light.eth.linkpool.io" zksync: provider_url: "https://rinkeby-api.zksync.io/jsrpc" @@ -234,176 +235,14 @@ zksync: res: - result: "sync-tx:4f8b59a5d7d4f128c3024b481eebc66de41428636c385ca68f00ea5f0d785564" - - - extra: "with multisig" - config: - proof: 'none' - experimental: true - pk: "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" - rpc: "https://rinkeby-light.eth.linkpool.io" - zksync: - provider_url: "https://rinkeby-api.zksync.io/jsrpc" - account: "0x448d2286d9d6996241ff1f87bd2e24692975cabd" - sync_key: "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" - musig_pub_keys: "0x5303a0015f8d5a8fef6cb1d60a034ef28dc4ac6aefa33c936d5aa0927f7c169a4a646591170aee46931ade1148038c4c75c3972af2281a580756a0317c19872d" - musig_urls: - - "" - - "https://approver.incubed.net" - create2: - creator: "0xaa8c54c65c14f132804f0809bdbef19970673709" - saltarg: "0x3bf6b1cbce10cee9cba978f4f2466ccaf1802af73f15a0f1dd8bff9e666bf2d8" - codehash: "0x96657bf6bdcbffce06518530907d2d729e4659ad3bc7b5cc1f5c5567d964272c" - create_proof_method: "zk_wallet_create_signatures" - wallets: - - - type: "l2" - address: "0x448d2286d9d6996241ff1f87bd2e24692975cabd" - threshold: 1 - signer: "0x5303a0015f8d5a8fef6cb1d60a034ef28dc4ac6aefa33c936d5aa0927f7c169a" - owners: - - - roles: 6 - address: "0x8d33caff9b73a3eb24c83ac79bb5ed56126f284c" - - - roles: 4 - address: "0x082977959d0c5a1ba627720ac753ec2adb5bd7d0" - input: - - "ETH" - expected_output: "sync:ec0de4692863fc7b1459cb98c6be56ada438d991" - mockedResponses: - - eth_chainId: - req: - - - method: "eth_chainId" - params: [] - res: - - - result: "0x4" - - account_info: - req: - - - method: "account_info" - params: - - "0x448d2286d9d6996241ff1f87bd2e24692975cabd" - res: - - - jsonrpc: '2.0' - id: 1 - result: - depositing: - balances: {} - committed: - nonce: 0 - balances: - ETH: '100000000000000000' - nfts: {} - mintedNfts: {} - pubKeyHash: 'sync:0000000000000000000000000000000000000000' - id: 167081 - verified: - nonce: 0 - balances: - ETH: "100000000000000000" - nfts: {} - mintedNfts: {} - pubKeyHash: 'sync:0000000000000000000000000000000000000000' - address: '0x448d2286d9d6996241ff1f87bd2e24692975cabd' - - tokens: - req: - - - method: "tokens" - params: [] - res: - - - result: *tokens - - get_tx_fee: - req: - - - method: "get_tx_fee" - params: - - - ChangePubKey: - onchainPubkeyAuth: true - - "0x448d2286d9d6996241ff1f87bd2e24692975cabd" - - "ETH" - res: - - - result: - zkpFee: 33120446126802 - totalFee: 43000000000000 - gasTxAmount: 7600 - gasPriceWei: 1000000000 - gasFee: 9880000000000 - feeType: - ChangePubKey: - onchainPubkeyAuth: true - - tx_submit: - req: - - - method: "tx_submit" - params: - - - nonce: 0 - fee: "64600000000000" - validUntil: 4294967295 - type: "ChangePubKey" - ethAuthData: - type: "ECDSA" - ethSignature: "0x2b281880b7c73127570aaa4696ea6024f826977649d15fc37e422ffc996121153a909302fad27e4548c66c7e0520b6f77c5027c88104b38fe82af16b85d4c7061b" - accountId: 167067 - signature: - pubKey: "1604e29d6544afa77334fce3964f68b01cdedbbdaf739355311195fd25292f04" - signature: "c936c89a624dc5effbb54bd3b2a2d56f4deac9103051d4607476770c3451d321784751218821e73f2f4d514068cd2bfd511bc4137fa28bdb660682944a754001" - validFrom: 0 - account: "0x8d33caff9b73a3eb24c83ac79bb5ed56126f284c" - feeToken: 0 - feeTokenId: 0 - newPkHash: "sync:ec0de4692863fc7b1459cb98c6be56ada438d991" - - null - - false - res: - - - result: "sync-tx:4f8b59a5d7d4f128c3024b481eebc66de41428636c385ca68f00ea5f0d785564" - - zk_sign: - req: - - - method: "zk_sign" - params: - - - message: "0x0700028ca9448d2286d9d6996241ff1f87bd2e24692975cabde9d10277efa866916138305467cfca1858b5b3f6000035cb00000000000000000000000000000000ffffffff" - proof: - - "0xd693cf7edf35ae80a6117fddace9faf23c23b66f4ff925d0312f32a7da7585ea321cd6fd7ae0e7a81029422d6b1dc0c26cf1bcf626d9adb412555eedfee0c3d21c" - pub_keys: "0x5303a0015f8d5a8fef6cb1d60a034ef28dc4ac6aefa33c936d5aa0927f7c169a4a646591170aee46931ade1148038c4c75c3972af2281a580756a0317c19872d" - pre_commitment: "0x7f5588233f6d50792a05146fc73260c7b336baa27364d07ca4460a68c8118b390000000000000000000000000000000000000000000000000000000000000000" - account: "0x448d2286d9d6996241ff1f87bd2e24692975cabd" - - - method: "zk_sign" - params: - - - account: "0x448d2286d9d6996241ff1f87bd2e24692975cabd" - commitment: "0x9bf75261a1372a9694d3e8764e62a8ddb747eca5219d2f8447b0a81d48d30010a9bd94d7d2fc244fe993a1dae294d08774da17b7588481aae34facdca327e288" - message: "0x0700028ca9448d2286d9d6996241ff1f87bd2e24692975cabde9d10277efa866916138305467cfca1858b5b3f6000035cb00000000000000000000000000000000ffffffff" - proof: - - "0xd693cf7edf35ae80a6117fddace9faf23c23b66f4ff925d0312f32a7da7585ea321cd6fd7ae0e7a81029422d6b1dc0c26cf1bcf626d9adb412555eedfee0c3d21c" - pub_keys: "0x5303a0015f8d5a8fef6cb1d60a034ef28dc4ac6aefa33c936d5aa0927f7c169a4a646591170aee46931ade1148038c4c75c3972af2281a580756a0317c19872d" - sig: "0x050394325427a033c78a314340be3b22f843bf110f67dfa1a48668512be66d610000000000000000000000000000000000000000000000000000000000000000" - pre_commitment: "0x7f5588233f6d50792a05146fc73260c7b336baa27364d07ca4460a68c8118b39b46c017ea874fad0b07e87bf227099e916ba4d355730c2de5830162623127d49" - res: - - - result: - commitment: "0x0000000000000000000000000000000000000000000000000000000000000000a9bd94d7d2fc244fe993a1dae294d08774da17b7588481aae34facdca327e288" - pre_commitment: "0x7f5588233f6d50792a05146fc73260c7b336baa27364d07ca4460a68c8118b39b46c017ea874fad0b07e87bf227099e916ba4d355730c2de5830162623127d49" - - - result: - sig: "0x050394325427a033c78a314340be3b22f843bf110f67dfa1a48668512be66d61042517e6807360fab026dab1979ca27a2e1f80a8eacf178f8504283fa46dd025" - pre_commitment: "0x7f5588233f6d50792a05146fc73260c7b336baa27364d07ca4460a68c8118b39b46c017ea874fad0b07e87bf227099e916ba4d355730c2de5830162623127d49" - commitment: "0x9bf75261a1372a9694d3e8764e62a8ddb747eca5219d2f8447b0a81d48d30010a9bd94d7d2fc244fe993a1dae294d08774da17b7588481aae34facdca327e288" zksync_transfer: + - config: proof: 'none' experimental: true - pk: "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" + pk: + - "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" rpc: "https://rinkeby-light.eth.linkpool.io" zksync: provider_url: "https://rinkeby-api.zksync.io/jsrpc" @@ -514,13 +353,134 @@ zksync: res: - result: "sync-tx:b431fad24a0b3ccc324c09b1dd3f2484ac070d944a615e46d7b822dd9e883c02" - + + - + extra: "with l2 wallet" + config: + proof: 'none' + experimental: true + rpc: "https://rinkeby-light.eth.linkpool.io" + zksync: + provider_url: "https://rinkeby-api.zksync.io/jsrpc" + sync_key: "0x49db8b7407712dc2f013fac325596e0440af21192d8dbced73aec9f8d97c8ea5" + verify_proof_method: "zk_wallet_verify_signatures" + create_proof_method: "zk_wallet_create_signatures" + musig_urls: + - null + - "https://approver.incubed.net" + wallet_deploy: + creator: "0xaa8c54c65c14f132804f0809bdbef19970673709" + master_copy: "0xc73248bb521c3331e4efedbb0560e806302024fb" + add_module: "0x846A192315882ca369125F82E64e368858663898" + master_copy_custody: "0x937c53Cad1619a996645165129620eF2853c76B0" + default_wallet: "0x537f989e56dca9a3937588fc61639f634359fc88" + default_exec: "receipt" + pk: + - "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" + - "0xc720d9404dc73ad831faf6ee7a55b21b30c285279dca09cfbd0015b2f05aff9b" + - "0xb66d5d63a837364c30ed9b9b0ca717e985fb694749ae4e9e12280ccc120109b0" + wallets: + - + sync_key: "0xb87e956f29eabf3878120ce97909c4f383f18e0f49d8fe7d0626a80ec9b8925f" + address: "0x537f989e56dca9a3937588fc61639f634359fc88" + threshold: 2 + type: "l2" + signer: "0xce4a5107ecdd523876deedc1a59600bff3ea7852cd1feec1a48f89bc459ae58b" + owners: + - + roles: 7 + address: "0x0d065af76869fa17525e3b0d3f3e29d9577a4501" + - + roles: 7 + address: "0x827415a37def6e0953e6b417cfe81066e3387528" + - + roles: 1 + address: "0x937c53cad1619a996645165129620ef2853c76b0" + master_copy_custody: "0x937c53cad1619a996645165129620ef2853c76b0" + create_module: "0x846a192315882ca369125f82e64e368858663898" + master_copy: "0xc73248bb521c3331e4efedbb0560e806302024fb" + cosign_url: "https://approver.incubed.net" + rpc_url: "https://rinkeby-api.zksync.io/jsrpc" + creator: "0xaa8c54c65c14f132804f0809bdbef19970673709" + saltarg: "0xe1b8515c341dfbfaa08a440019c48a66c4523263a524bf5199e0a51f86bebccf" + codehash: "0x96657bf6bdcbffce06518530907d2d729e4659ad3bc7b5cc1f5c5567d964272c" + musig_pub_keys: "0xce4a5107ecdd523876deedc1a59600bff3ea7852cd1feec1a48f89bc459ae58b4a646591170aee46931ade1148038c4c75c3972af2281a580756a0317c19872d" + - + sync_key: "0xde4525356411a77457679b43030d964784b39a5b4a0a1a5a2a82dd4fa35289a3" + address: "0x98e0df4929d07b9e542b1cae0cd42ca4e055366d" + threshold: 2 + type: "l1l2" + owners: + - + roles: 7 + address: "0x0d065af76869fa17525e3b0d3f3e29d9577a4501" + - + roles: 7 + address: "0x827415a37def6e0953e6b417cfe81066e3387528" + - roles: 1 + address: "0x937c53cad1619a996645165129620ef2853c76b0" + creator: "0xaa8c54c65c14f132804f0809bdbef19970673709" + master_copy: "0xc73248bb521c3331e4efedbb0560e806302024fb" + master_copy_custody: "0x937c53cad1619a996645165129620ef2853c76b0" + create_module: "0x846a192315882ca369125f82e64e368858663898" + custody: "0xd95c6d04d048c6863394252da421a1165b87182a" + safetype: "IAMO Safe" + - + address: "0x8D33cAFf9b73A3EB24c83ac79bb5eD56126f284C" + type: "l1l2pk" + input: + - "0x448d2286d9d6996241ff1f87bd2e24692975cabd" + - "100000000000000000" + - "ETH" + expected_output: + type: 'Transfer' + accountId: 167067 + from: "0x8d33caff9b73a3eb24c83ac79bb5ed56126f284c" + to: "0x448d2286d9d6996241ff1f87bd2e24692975cabd" + token: 0 + tokenId: 0 + amount: "100000000000000000" + fee: "30300000000000" + validFrom: 0 + validUntil: 4294967295 + nonce: 3 + txHash: "sync-tx:b431fad24a0b3ccc324c09b1dd3f2484ac070d944a615e46d7b822dd9e883c02" + mockedResponses: + - account_info: + req: + - + method: "account_info" + params: + - "0x537f989e56dca9a3937588fc61639f634359fc88" + res: + - + result: + address: "0x537f989e56dca9a3937588fc61639f634359fc88" + id: "189462" + depositing: + balances: {} + committed: + balances: + ETH: "100000000000000000" + nfts: {} + mintedNfts: {} + nonce: 0 + pubKeyHash: "sync:0000000000000000000000000000000000000000" + verified: + balances: {} + nfts: {} + mintedNfts: {} + nonce: 0 + pubKeyHash: "sync:0000000000000000000000000000000000000000" + + zksync_deposit: config: proof: 'none' experimental: true - pk: "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" + pk: + - "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" rpc: "https://rinkeby-light.eth.linkpool.io" zksync: provider_url: "https://rinkeby-api.zksync.io/jsrpc" @@ -675,7 +635,8 @@ zksync: config: proof: 'none' experimental: true - pk: "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" + pk: + - "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" rpc: 'https://rinkeby-light.eth.linkpool.io' zksync: provider_url: 'https://rinkeby-light.eth.linkpool.io' @@ -793,7 +754,8 @@ zksync: config: proof: 'none' experimental: true - pk: "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" + pk: + - "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" rpc: 'https://rinkeby-light.eth.linkpool.io' zksync: provider_url: 'https://rinkeby-light.eth.linkpool.io' @@ -933,7 +895,8 @@ zksync: config: proof: 'none' experimental: true - pk: "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" + pk: + - "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" expected_output: mainContract: "0x82f67958a5474e40e1485742d648c0b0686b6e5d" govContract: "0xc8568f373484cd51fdc1fe3675e46d8c0dc7d246" @@ -953,7 +916,8 @@ zksync: config: proof: 'none' experimental: true - pk: "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" + pk: + - "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" expected_output: USDC: decimals: 6 @@ -1074,7 +1038,8 @@ zksync: config: proof: 'none' experimental: true - pk: "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" + pk: + - "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" input: - "0x5303a0015f8d5a8fef6cb1d60a034ef28dc4ac6aefa33c936d5aa0927f7c169a" expected_output: "sync:827a841d753a8eefe82e02b25b5158305dab4d58" @@ -1083,21 +1048,24 @@ zksync: config: proof: 'none' experimental: true - pk: "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" + pk: + - "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" expected_output: "0xd274ec1a5e9a513ff8f4eeb344fc02ca61e0823a7821c76e459ea0e8c5140826" zksync_account_address: config: proof: 'none' experimental: true - pk: "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" + pk: + - "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" expected_output: "0x8d33caff9b73a3eb24c83ac79bb5ed56126f284c" zksync_sign: config: proof: 'none' experimental: true - pk: "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" + pk: + - "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" input: - "0xaabbccddeeff" expected_output: "0xd274ec1a5e9a513ff8f4eeb344fc02ca61e0823a7821c76e459ea0e8c5140826d78eb2c9661541f31ca097f5d38dc39aa9813017b4db929242e8e633839bdc80e4df4cbc14f9c8ca530c95ac005646c4b4b00f0a52a3dcb588db14b86fd66f02" @@ -1106,7 +1074,8 @@ zksync: config: proof: 'none' experimental: true - pk: "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" + pk: + - "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" input: - "0xaabbccddeeff" - "0x5303a0015f8d5a8fef6cb1d60a034ef28dc4ac6aefa33c936d5aa0927f7c169a52196178c5023fe88a56872439330bdd1c6c9578cb6e996dfcb704c52ae24a837e6acd5024aca9f5b5507e61cd4388c848a5752ef5e961e10d73b29b4a6b3902" @@ -1116,7 +1085,8 @@ zksync: config: proof: 'none' experimental: true - pk: "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" + pk: + - "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" input: - "ETH" expected_output: 214.996782624198 @@ -1135,7 +1105,8 @@ zksync: config: proof: 'none' experimental: true - pk: "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" + pk: + - "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" input: - "Transfer" - "0xabea9132b05a70803a4e85094fd0e1800777fbef" @@ -1170,14 +1141,16 @@ zksync: config: proof: 'none' experimental: true - pk: "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" + pk: + - "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" expected_output: "0x0492fb6558207a6e006870bdaeab911e490ff9cedb0c8eca67560122ac2f7256" zksync_aggregate_pubkey: config: proof: 'none' experimental: true - pk: "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" + pk: + - "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" input: - "0x0f61bfe164cc43b5a112bfbfb0583004e79dbfafc97a7daad14c5d511fea8e2435065ddd04329ec94be682bf004b03a5a4eeca9bf50a8b8b6023942adc0b3409" expected_output: "0x9ce5b6f8db3fbbe66a3bdbd3b4731f19ec27f80ee03ead3c0708798dd949882b" @@ -1186,7 +1159,8 @@ zksync: config: proof: 'none' experimental: true - pk: "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" + pk: + - "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" zksync: rest_api: "https://rinkeby-api.zksync.io/api/v0.1" input: @@ -1255,7 +1229,8 @@ zksync: config: proof: 'none' experimental: true - pk: "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" + pk: + - "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" zksync: rest_api: "https://rinkeby-api.zksync.io/api/v0.1" input: @@ -1371,7 +1346,8 @@ zksync: config: proof: 'none' experimental: true - pk: "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" + pk: + - "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" input: - "0x0e8b4fe889b126b9b502b244c9130912510f014f" expected_output: @@ -1422,7 +1398,8 @@ zksync: config: proof: 'none' experimental: true - pk: "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" + pk: + - "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" input: - "sync-tx:e41d2489571d322189246dafa5ebde1f4699f498000000000000000000000000" expected_output: @@ -1449,7 +1426,8 @@ zksync: config: proof: 'none' experimental: true - pk: "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" + pk: + - "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" input: - 1 expected_output: diff --git a/c/src/signer/pk-signer/rpc.yml b/c/src/signer/pk-signer/rpc.yml index 162a25c05..df03cf14f 100644 --- a/c/src/signer/pk-signer/rpc.yml +++ b/c/src/signer/pk-signer/rpc.yml @@ -1,19 +1,19 @@ account: - # config config: - key: type: bytes32 descr: the client key to sign requests. (only availble if build with `-DPK_SIGNER=true` , which is on per default) example: "0xc9564409cbfca3f486a07996e8015124f30ff8331fc6dcbd610a050f1f983afe" optional: true cmd: k - + pk: - type: bytes32|bytes32[] + type: bytes32 + array: true descr: registers raw private keys as signers for transactions. (only availble if build with `-DPK_SIGNER=true` , which is on per default) - example: ["0xc9564409cbfca3f486a07996e8015124f30ff8331fc6dcbd610a050f1f983afe"] + example: + ["0xc9564409cbfca3f486a07996e8015124f30ff8331fc6dcbd610a050f1f983afe"] optional: true cmd: pk @@ -37,18 +37,13 @@ account: sync: true descr: | returns a array of account-addresss the incubed client is able to sign with. - + In order to add keys, you can use [in3_addRawKey](#in3-addrawkey) or configure them in the config. The result also contains the addresses of any signer signer-supporting the `PLGN_ACT_SIGN_ACCOUNT` action. result: descr: the array of addresses of all registered signers. array: true type: address example: - response: + response: - "0x2e988a386a799f506693793c6a5af6b54dfaabfb" - "0x93793c6a5af6b54dfaabfb2e988a386a799f5066" - - - - - diff --git a/c/src/signer/pk-signer/testCases.yml b/c/src/signer/pk-signer/testCases.yml index 572d1e266..e5292a698 100644 --- a/c/src/signer/pk-signer/testCases.yml +++ b/c/src/signer/pk-signer/testCases.yml @@ -9,6 +9,7 @@ account: - expected_output: [] - config: - pk: "0x4d5db4107d237df6a3d58ee5f70ae63d73d7658d4026f2eefd2f204c81682cb7" + pk: + - "0x4d5db4107d237df6a3d58ee5f70ae63d73d7658d4026f2eefd2f204c81682cb7" expected_output: - "0x00a329c0648769a73afac7f9381e08fb43dbea72" \ No newline at end of file diff --git a/c/src/verifier/eth1/basic/testCases.yml b/c/src/verifier/eth1/basic/testCases.yml index 1f1738afd..8f0ee9833 100644 --- a/c/src/verifier/eth1/basic/testCases.yml +++ b/c/src/verifier/eth1/basic/testCases.yml @@ -492,7 +492,8 @@ eth: eth_sendTransaction: config: proof: 'none' - pk: "0x4d5db4107d237df6a3d58ee5f70ae63d73d7658d4026f2eefd2f204c81682cb7" + pk: + - "0x4d5db4107d237df6a3d58ee5f70ae63d73d7658d4026f2eefd2f204c81682cb7" chainId: 'goerli' input: - @@ -517,7 +518,8 @@ eth: eth_sendTransactionAndWait: config: proof: 'none' - pk: "0x4d5db4107d237df6a3d58ee5f70ae63d73d7658d4026f2eefd2f204c81682cb7" + pk: + - "0x4d5db4107d237df6a3d58ee5f70ae63d73d7658d4026f2eefd2f204c81682cb7" chainId: 'goerli' input: - @@ -636,7 +638,8 @@ eth: eth_sendRawTransaction: config: proof: 'none' - pk: "0x4d5db4107d237df6a3d58ee5f70ae63d73d7658d4026f2eefd2f204c81682cb7" + pk: + - "0x4d5db4107d237df6a3d58ee5f70ae63d73d7658d4026f2eefd2f204c81682cb7" chainId: 'goerli' input: - "0xf86d8206aa85438558d400825208941ebd5c8cfec45650cf9c80adfeb5488ae36859c3872386f26fc10000801ba06df6fc901a78cea1dfc02baead56c8ec0d8d008c505efcfc3b4462b1a659be25a065152fd2e0dbf04b8e1baac46f31df9033f9c72b9dfad1b4fe41f89ef32c9a53" From 28ee295dc21a1fc88e81851e5c35783beffc19db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20K=C3=BCchler?= Date: Tue, 13 Jul 2021 10:06:23 +0200 Subject: [PATCH 007/101] OnChain fix --- c/src/pay/zksync/zk_message.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/c/src/pay/zksync/zk_message.c b/c/src/pay/zksync/zk_message.c index 765a05176..0bd9fe8ba 100644 --- a/c/src/pay/zksync/zk_message.c +++ b/c/src/pay/zksync/zk_message.c @@ -325,7 +325,7 @@ in3_ret_t zksync_sign_change_pub_key(sb_t* sb, in3_req_t* ctx, uint8_t* sync_pub if (conf->sign_type == ZK_SIGN_PK) sb_add_rawbytes(sb, "\"type\":\"ECDSA\",\"ethSignature\":\"0x", signature, 0); else if (conf->sign_type == ZK_SIGN_CONTRACT) - sb_add_rawbytes(sb, "\"type\":\"Onchain", signature, 0); + sb_add_chars(sb, "\"type\":\"Onchain"); else if (conf->sign_type == ZK_SIGN_CREATE2) { sb_add_rawbytes(sb, "\"type\":\"CREATE2\",\"creatorAddress\":\"0x", bytes(conf->create2.creator, 20), 0); sb_add_rawbytes(sb, "\",\"saltArg\":\"0x", bytes(conf->create2.salt_arg, 32), 0); From 4e021e16a585fa3301eb380aacb1abee146a2175 Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Mon, 2 Aug 2021 13:54:15 +0200 Subject: [PATCH 008/101] fix json-parser for simple numbers --- c/src/core/util/data.c | 1 + 1 file changed, 1 insertion(+) diff --git a/c/src/core/util/data.c b/c/src/core/util/data.c index 6b30bb49d..b285366b5 100644 --- a/c/src/core/util/data.c +++ b/c/src/core/util/data.c @@ -402,6 +402,7 @@ static NONULL int parse_number(json_ctx_t* jp, d_token_t* item) { case '}': case ']': case ',': + case 0: if ((value & 0xfffffffff0000000) == 0) // is it small ennough to store it in the length ? item->len |= (uint32_t) value; // 32-bit number / no 64-bit number From 4fddd29cc85d409d0df01b0a7a89d729cb86a508 Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Tue, 3 Aug 2021 11:53:02 +0200 Subject: [PATCH 009/101] fix fee calc --- c/src/pay/zksync/zk_setkey.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/c/src/pay/zksync/zk_setkey.c b/c/src/pay/zksync/zk_setkey.c index eece5a302..2e48d2719 100644 --- a/c/src/pay/zksync/zk_setkey.c +++ b/c/src/pay/zksync/zk_setkey.c @@ -88,7 +88,13 @@ in3_ret_t zksync_set_key(zksync_config_t* conf, in3_rpc_handle_ctx_t* ctx, bool if (conf->sign_type == ZK_SIGN_CONTRACT) TRY(auth_pub_key(conf, ctx, nonce, pub_hash)) // get fees - TRY(zksync_get_fee(conf, ctx->req, NULL, bytes(conf->account, 20), token, conf->sign_type == ZK_SIGN_PK ? "{\"ChangePubKey\":{\"onchainPubkeyAuth\":false}}" : "{\"ChangePubKey\":{\"onchainPubkeyAuth\":true}}", + // 'Onchain' | 'ECDSA' | 'CREATE2' | 'ECDSALegacyMessage'; + char* keytype = "{\"ChangePubKey\":\"ECDSA\"}"; + if (conf->sign_type == ZK_SIGN_CREATE2) + keytype = "{\"ChangePubKey\":\"CREATE2\"}"; + else if (conf->sign_type == ZK_SIGN_CONTRACT) + keytype = "{\"ChangePubKey\":\"Onchain\"}"; + TRY(zksync_get_fee(conf, ctx->req, NULL, bytes(conf->account, 20), token, keytype, #ifdef ZKSYNC_256 fee #else From 335e399a173be1b14c2b4da310fc12ca63ac5e63 Mon Sep 17 00:00:00 2001 From: leonardotc Date: Thu, 5 Aug 2021 12:24:16 +0200 Subject: [PATCH 010/101] Fix interface for musig url on zksync declaration --- c/src/pay/zksync/rpc.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/c/src/pay/zksync/rpc.yml b/c/src/pay/zksync/rpc.yml index 210eb82e5..84e2ef1ae 100644 --- a/c/src/pay/zksync/rpc.yml +++ b/c/src/pay/zksync/rpc.yml @@ -306,6 +306,7 @@ zksync: type: string array: true optional: true + nullable: true cmd: zmu create2: From e56cd9474b3bedcc9ad49c811b6148338a561f8f Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Thu, 12 Aug 2021 15:12:49 +0200 Subject: [PATCH 011/101] add payload type --- c/include/in3/plugin.h | 20 +++++++++++++++----- c/src/core/client/plugin.h | 20 +++++++++++++++----- c/src/core/client/request.c | 7 +++++-- c/src/core/client/request_internal.h | 2 +- c/src/pay/zksync/zk_helper.c | 2 +- c/src/pay/zksync/zk_message.c | 4 ++-- c/src/signer/multisig/multisig.c | 2 +- c/src/verifier/eth1/basic/sign_tx.c | 2 +- 8 files changed, 41 insertions(+), 18 deletions(-) diff --git a/c/include/in3/plugin.h b/c/include/in3/plugin.h index d7b9d01f5..f6412397b 100644 --- a/c/include/in3/plugin.h +++ b/c/include/in3/plugin.h @@ -289,15 +289,25 @@ typedef enum { SIGN_EC_PREFIX = 2, /**< add Ethereum Signed Message-Proefix, hash and sign the data */ } d_signature_type_t; +/** payload type of the requested signature. It describes how to deserialize the payload. */ +typedef enum { + PL_SIGN_ANY = 0, /**< custom data to be signed*/ + PL_SIGN_ETHTX = 1, /**< the payload is a ethereum-tx */ + PL_SIGN_BTCTX = 2, /**< the payload is a BTC-Tx-Input */ + PL_SIGN_SAFETX = 3, /**< The payload is a rlp-encoded data of a Gnosys Safe Tx */ +} d_payload_type_t; + /** * signing context. This Context is passed to the signer-function. */ typedef struct sign_ctx { - bytes_t signature; /**< the resulting signature */ - d_signature_type_t type; /**< the type of signature*/ - struct in3_req* req; /**< the context of the request in order report errors */ - bytes_t message; /**< the message to sign*/ - bytes_t account; /**< the account to use for the signature */ + bytes_t signature; /**< the resulting signature */ + d_signature_type_t type; /**< the type of signature*/ + d_payload_type_t payload_type; /**< the type of payload in order to deserialize the payload */ + struct in3_req* req; /**< the context of the request in order report errors */ + bytes_t message; /**< the message to sign*/ + bytes_t account; /**< the account to use for the signature */ + d_token_t* meta; /**< optional metadata to pass a long, which could include data to present to the user before signing */ } in3_sign_ctx_t; /** diff --git a/c/src/core/client/plugin.h b/c/src/core/client/plugin.h index d7b9d01f5..f6412397b 100644 --- a/c/src/core/client/plugin.h +++ b/c/src/core/client/plugin.h @@ -289,15 +289,25 @@ typedef enum { SIGN_EC_PREFIX = 2, /**< add Ethereum Signed Message-Proefix, hash and sign the data */ } d_signature_type_t; +/** payload type of the requested signature. It describes how to deserialize the payload. */ +typedef enum { + PL_SIGN_ANY = 0, /**< custom data to be signed*/ + PL_SIGN_ETHTX = 1, /**< the payload is a ethereum-tx */ + PL_SIGN_BTCTX = 2, /**< the payload is a BTC-Tx-Input */ + PL_SIGN_SAFETX = 3, /**< The payload is a rlp-encoded data of a Gnosys Safe Tx */ +} d_payload_type_t; + /** * signing context. This Context is passed to the signer-function. */ typedef struct sign_ctx { - bytes_t signature; /**< the resulting signature */ - d_signature_type_t type; /**< the type of signature*/ - struct in3_req* req; /**< the context of the request in order report errors */ - bytes_t message; /**< the message to sign*/ - bytes_t account; /**< the account to use for the signature */ + bytes_t signature; /**< the resulting signature */ + d_signature_type_t type; /**< the type of signature*/ + d_payload_type_t payload_type; /**< the type of payload in order to deserialize the payload */ + struct in3_req* req; /**< the context of the request in order report errors */ + bytes_t message; /**< the message to sign*/ + bytes_t account; /**< the account to use for the signature */ + d_token_t* meta; /**< optional metadata to pass a long, which could include data to present to the user before signing */ } in3_sign_ctx_t; /** diff --git a/c/src/core/client/request.c b/c/src/core/client/request.c index 2072a80fd..5c14f93d9 100644 --- a/c/src/core/client/request.c +++ b/c/src/core/client/request.c @@ -422,7 +422,7 @@ in3_ret_t req_send_sub_request(in3_req_t* parent, char* method, char* params, ch return ret; } -in3_ret_t req_require_signature(in3_req_t* ctx, d_signature_type_t type, bytes_t* signature, bytes_t raw_data, bytes_t from) { +in3_ret_t req_require_signature(in3_req_t* ctx, d_signature_type_t type, d_payload_type_t pl_type, bytes_t* signature, bytes_t raw_data, bytes_t from, d_token_t* meta) { bytes_t cache_key = bytes(alloca(raw_data.len + from.len), raw_data.len + from.len); memcpy(cache_key.data, raw_data.data, raw_data.len); if (from.data) memcpy(cache_key.data + raw_data.len, from.data, from.len); @@ -436,7 +436,7 @@ in3_ret_t req_require_signature(in3_req_t* ctx, d_signature_type_t type, bytes_t // first try internal plugins for signing, before we create an context. if (in3_plugin_is_registered(ctx->client, PLGN_ACT_SIGN)) { - in3_sign_ctx_t sc = {.account = from, .req = ctx, .message = raw_data, .signature = NULL_BYTES, .type = type}; + in3_sign_ctx_t sc = {.account = from, .req = ctx, .message = raw_data, .signature = NULL_BYTES, .type = type, .payload_type = pl_type, .meta = meta}; in3_ret_t r = in3_plugin_execute_first_or_none(ctx, PLGN_ACT_SIGN, &sc); if (r == IN3_OK && sc.signature.data) { in3_cache_add_entry(&ctx->cache, cloned_bytes(cache_key), sc.signature); @@ -480,6 +480,9 @@ in3_ret_t req_require_signature(in3_req_t* ctx, d_signature_type_t type, bytes_t sb_add_bytes(&req, "\",\"params\":[", &raw_data, 1, false); sb_add_chars(&req, ","); sb_add_bytes(&req, NULL, &from, 1, false); + sb_add_chars(&req, ","); + sb_add_int(&req, (int64_t) pl_type); + sb_add_json(&req, ",", meta); sb_add_chars(&req, "]}"); c = req_new(ctx->client, req.data); if (!c) return IN3_ECONFIG; diff --git a/c/src/core/client/request_internal.h b/c/src/core/client/request_internal.h index c0036187c..6eb926d04 100644 --- a/c/src/core/client/request_internal.h +++ b/c/src/core/client/request_internal.h @@ -94,7 +94,7 @@ in3_ret_t req_handle_failable( NONULL_FOR((1, 2, 3, 5)) in3_ret_t req_send_sub_request(in3_req_t* parent, char* method, char* params, char* in3, d_token_t** result, in3_req_t** child); -NONULL in3_ret_t req_require_signature(in3_req_t* req, d_signature_type_t type, bytes_t* sig, bytes_t raw_data, bytes_t from); +NONULL in3_ret_t req_require_signature(in3_req_t* ctx, d_signature_type_t type, d_payload_type_t pl_type, bytes_t* signature, bytes_t raw_data, bytes_t from, d_token_t* meta); NONULL in3_ret_t in3_retry_same_node(in3_req_t* req); #define assert_in3_req(ctx) \ diff --git a/c/src/pay/zksync/zk_helper.c b/c/src/pay/zksync/zk_helper.c index c5b52060f..e37be4064 100644 --- a/c/src/pay/zksync/zk_helper.c +++ b/c/src/pay/zksync/zk_helper.c @@ -197,7 +197,7 @@ in3_ret_t zksync_get_sync_key(zksync_config_t* conf, in3_req_t* ctx, uint8_t* sy } TRY(zksync_get_account(conf, ctx, &account)) assert(account); - TRY(req_require_signature(ctx, SIGN_EC_PREFIX, &signature, bytes((uint8_t*) message, strlen(message)), bytes(account, 20))) + TRY(req_require_signature(ctx, SIGN_EC_PREFIX, PL_SIGN_ANY, &signature, bytes((uint8_t*) message, strlen(message)), bytes(account, 20), ctx->requests[0])) if (signature.len == 65 && signature.data[64] < 2) signature.data[64] += 27; zkcrypto_pk_from_seed(signature, conf->sync_key); diff --git a/c/src/pay/zksync/zk_message.c b/c/src/pay/zksync/zk_message.c index a53e4d891..5b1511014 100644 --- a/c/src/pay/zksync/zk_message.c +++ b/c/src/pay/zksync/zk_message.c @@ -180,7 +180,7 @@ in3_ret_t zksync_sign_transfer(sb_t* sb, zksync_tx_data_t* data, in3_req_t* ctx, if (data->prepare) data->prepare->human_message = _strdupn(msg_data, -1); else { - TRY(req_require_signature(ctx, SIGN_EC_PREFIX, &signature, bytes((uint8_t*) msg_data, msg.len), bytes(data->from, 20))) + TRY(req_require_signature(ctx, SIGN_EC_PREFIX, PL_SIGN_ANY, &signature, bytes((uint8_t*) msg_data, msg.len), bytes(data->from, 20), ctx->requests[0])) in3_log_debug("zksync_sign_transfer human readable :\n%s\n", msg_data); if (signature.len == 65 && signature.data[64] < 27) @@ -294,7 +294,7 @@ in3_ret_t zksync_sign_change_pub_key(sb_t* sb, in3_req_t* ctx, uint8_t* sync_pub memset(ethmsg + 28, 0, 32); // msgBatch hash - currently not supported, so 32x0 if (conf->sign_type != ZK_SIGN_CREATE2) { - TRY(req_require_signature(ctx, SIGN_EC_PREFIX, &signature, bytes((uint8_t*) ethmsg, 60), bytes(conf->account, 20))) + TRY(req_require_signature(ctx, SIGN_EC_PREFIX, PL_SIGN_ANY, &signature, bytes((uint8_t*) ethmsg, 60), bytes(conf->account, 20), ctx->requests[0])) if (signature.len == 65 && signature.data[64] < 27) signature.data[64] += 27; // because EIP155 chainID = 0 } diff --git a/c/src/signer/multisig/multisig.c b/c/src/signer/multisig/multisig.c index f37edc250..fb7bdaa0b 100644 --- a/c/src/signer/multisig/multisig.c +++ b/c/src/signer/multisig/multisig.c @@ -504,7 +504,7 @@ in3_ret_t gs_create_contract_signature(multisig_t* ms, in3_sign_ctx_t* ctx) { uint8_t* account = sctx.accounts + i * 20; if (is_valid(sig_data, ms, account, sig_count)) { bytes_t signature = NULL_BYTES; - TRY(req_require_signature(ctx->req, SIGN_EC_RAW, &signature, bytes(hash, 32), bytes(account, 20))) + TRY(req_require_signature(ctx->req, SIGN_EC_RAW, PL_SIGN_SAFETX, &signature, bytes(hash, 32), bytes(account, 20), ctx->req->requests[0])) sig_data[sig_count].address = NULL; for (unsigned int n = 0; n < ms->owners_len; n++) { if (memcmp(ms->owners + n, account, 20) == 0) sig_data[sig_count].address = (void*) (ms->owners + n); diff --git a/c/src/verifier/eth1/basic/sign_tx.c b/c/src/verifier/eth1/basic/sign_tx.c index 758ad3f5e..8bdfee9b1 100644 --- a/c/src/verifier/eth1/basic/sign_tx.c +++ b/c/src/verifier/eth1/basic/sign_tx.c @@ -329,7 +329,7 @@ in3_ret_t eth_sign_raw_tx(bytes_t raw_tx, in3_req_t* ctx, address_t from, bytes_ chain_id = d_long(r); } - TRY(req_require_signature(ctx, SIGN_EC_HASH, &signature, raw_tx, bytes(from, 20))); + TRY(req_require_signature(ctx, SIGN_EC_HASH, PL_SIGN_ETHTX, &signature, raw_tx, bytes(from, 20), ctx->requests[0])); if (signature.len != 65) return req_set_error(ctx, "Transaction must be signed by a ECDSA-Signature!", IN3_EINVAL); // get the signature from required From d9486000c610d5b756dac9d7f84c30e0e5527b23 Mon Sep 17 00:00:00 2001 From: leonardotc Date: Fri, 13 Aug 2021 14:25:02 +0200 Subject: [PATCH 012/101] Fix status handloer for axios transport --- wasm/src/in3.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wasm/src/in3.js b/wasm/src/in3.js index 6b769b952..8fd615f44 100644 --- a/wasm/src/in3.js +++ b/wasm/src/in3.js @@ -90,7 +90,7 @@ else { const axios = require('' + 'axios') in3w.transport = (url, payload, timeout = 30000, method = "POST", headers = {}) => axios({ method: method || 'POST', url, data: JSON.parse(payload), timeout, headers: { 'Content-Type': 'application/json', 'User-Agent': 'in3 wasm ' + getVersion(), in3: 'wasm ' + getVersion(), ...headers } }) .then(res => { - if (res.status != 200) throw new HttpError("Invalid satus", res.status) + if (res.statusCode < 200 || res.statusCode >= 400) throw new HttpError("Invalid satus", res.status) return JSON.stringify(res.data) }) } catch (xx) { From 44931d5f8106ffb112eb8b85b882d046f075680c Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Tue, 17 Aug 2021 23:12:06 +0200 Subject: [PATCH 013/101] update types first --- scripts/generator/generate.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/generator/generate.js b/scripts/generator/generate.js index c42bd70c0..0e7b8b8cf 100755 --- a/scripts/generator/generate.js +++ b/scripts/generator/generate.js @@ -123,8 +123,12 @@ function handle_config(conf, pre, title, descr) { if (title) config_doc.push('\n## ' + title + '\n') for (const key of Object.keys(conf)) { const c = conf[key] + if (typeof (c.type) === 'string' && types[c.type]) { + c.typeName = c.type + c.type = types[c.type] + } // handle bindings - generators.forEach(_ => _.updateConfig(pre, c, key)) + generators.forEach(_ => _.updateConfig(pre, c, key, types)) // handle doc if (!pre) { From 8a8e3abefe5fac9da480ce4e570d73133a486b2c Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Wed, 18 Aug 2021 10:16:12 +0200 Subject: [PATCH 014/101] add check-macros --- c/src/core/util/debug.h | 52 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/c/src/core/util/debug.h b/c/src/core/util/debug.h index 939f2caf7..5974d3036 100644 --- a/c/src/core/util/debug.h +++ b/c/src/core/util/debug.h @@ -215,6 +215,58 @@ static inline void add_hex(sb_t* sb, char prefix, const char* property, bytes_t target = t->data; \ } +#define TRY_PARAM_GET_STRING(target, ctx, index, def) \ + { \ + const d_token_t* t = d_get_at(ctx->params, index); \ + if (d_type(t) == T_NULL) \ + target = def; \ + else if (d_type(t) != T_STRING) \ + return req_set_error(ctx->req, "Param at " #index " must be a valid string!", IN3_EINVAL); \ + else \ + target = d_string(t); \ + } + +#define TRY_PARAM_GET_REQUIRED_STRING(target, ctx, index) \ + { \ + const d_token_t* t = d_get_at(ctx->params, index); \ + if (d_type(t) != T_STRING) \ + return req_set_error(ctx->req, "Param at " #index " must be a valid string!", IN3_EINVAL); \ + else \ + target = d_string(t); \ + } + +#define TRY_PARAM_GET_OBJECT(target, ctx, index) \ + { \ + target = d_get_at(ctx->params, index); \ + if (d_type(target) == T_NULL) \ + target = NULL; \ + else if (d_type(target) != T_OBJECT) \ + return req_set_error(ctx->req, "Param at " #index " must be a valid object!", IN3_EINVAL); \ + } + +#define TRY_PARAM_GET_REQUIRED_OBJECT(target, ctx, index) \ + { \ + target = d_get_at(ctx->params, index); \ + if (d_type(target) != T_OBJECT) \ + return req_set_error(ctx->req, "Param at " #index " must be a valid object!", IN3_EINVAL); \ + } + +#define TRY_PARAM_GET_ARRAY(target, ctx, index) \ + { \ + target = d_get_at(ctx->params, index); \ + if (d_type(target) == T_NULL) \ + target = NULL; \ + else if (d_type(target) != T_ARRAY) \ + return req_set_error(ctx->req, "Param at " #index " must be a valid array!", IN3_EINVAL); \ + } + +#define TRY_PARAM_GET_REQUIRED_ARRAY(target, ctx, index) \ + { \ + target = d_get_at(ctx->params, index); \ + if (d_type(target) != T_ARRAY) \ + return req_set_error(ctx->req, "Param at " #index " must be a valid array!", IN3_EINVAL); \ + } + /** used for exeuting a function based on the name. This macro will return if the name matches. */ #endif /* DEBUG_H */ \ No newline at end of file From 1230db36145501d5c12cb66212e3096ac276865b Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Wed, 18 Aug 2021 10:33:33 +0200 Subject: [PATCH 015/101] add bytes-handlers --- c/src/core/util/debug.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/c/src/core/util/debug.h b/c/src/core/util/debug.h index 5974d3036..5bd998720 100644 --- a/c/src/core/util/debug.h +++ b/c/src/core/util/debug.h @@ -173,6 +173,26 @@ static inline void add_hex(sb_t* sb, char prefix, const char* property, bytes_t const d_token_t* val = d_get_at(params, index); \ if (!(cond)) return req_set_error(ctx, "argument at index " #index " must match " #cond, IN3_EINVAL); \ } +#define TRY_PARAM_GET_BYTES(target, ctx, index, min_len, max_len) \ + { \ + const d_token_t* t = d_get_at(ctx->params, index); \ + if (d_type(t) == T_NULL) \ + target = NULL_BYTES; \ + else if (d_type(t) == T_OBJECT || d_type(t) == T_ARRAY) \ + return req_set_error(ctx->req, "Param at " #index " must be bytes!", IN3_EINVAL); \ + else { \ + target = d_to_bytes(t); \ + if (target.len < min_len) return req_set_error(ctx->req, "Param at " #index " must have at least a length of " #min_len, IN3_EINVAL); \ + if (max_len && target.len > max_len) return req_set_error(ctx->req, "Param at " #index " must have max " #max_len "bytes", IN3_EINVAL); \ + } \ + } +#define TRY_PARAM_GET_REQUIRED_BYTES(target, ctx, index, min_len, max_len) \ + { \ + target = d_to_bytes(d_get_at(ctx->params, index)); \ + if (!target.data) return req_set_error(ctx->req, "Param at " #index " must be bytes!", IN3_EINVAL); \ + if (target.len < min_len) return req_set_error(ctx->req, "Param at " #index " must have at least a length of " #min_len, IN3_EINVAL); \ + if (max_len && target.len > max_len) return req_set_error(ctx->req, "Param at " #index " must have max " #max_len "bytes", IN3_EINVAL); \ + } #define TRY_PARAM_GET_INT(target, ctx, index, def) \ { \ From f47005ba3db9ec6528a5179f6ead148d3eb8d69a Mon Sep 17 00:00:00 2001 From: leonardotc Date: Wed, 18 Aug 2021 11:18:57 +0200 Subject: [PATCH 016/101] Fix transport to deal with empty strings --- c/src/core/client/execute.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/c/src/core/client/execute.c b/c/src/core/client/execute.c index 317969f7e..67658d5bf 100644 --- a/c/src/core/client/execute.c +++ b/c/src/core/client/execute.c @@ -250,7 +250,7 @@ NONULL static in3_ret_t ctx_parse_response(in3_req_t* ctx, char* response_data, assert_in3_req(ctx); assert(response_data); assert(len); - const bool is_json = response_data[0] == '{' || response_data[0] == '['; + const bool is_json = response_data[0] == '{' || response_data[0] == '[' || response_data[0] == '"'; if (is_raw_http(ctx)) { ctx->response_context = is_json ? parse_json(response_data) : NULL; From 5eaaa89457c3ea18a60f930b7f346693c5a12704 Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Wed, 18 Aug 2021 15:02:49 +0200 Subject: [PATCH 017/101] cleanup memory --- c/src/cmd/in3/main.c | 1 + c/src/tools/recorder/recorder.c | 18 ++++++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/c/src/cmd/in3/main.c b/c/src/cmd/in3/main.c index 3229cd532..eb04ba065 100644 --- a/c/src/cmd/in3/main.c +++ b/c/src/cmd/in3/main.c @@ -21,6 +21,7 @@ static void send_request(in3_t* c, int argc, char** argv, char* method, sb_t* ar else sb_add_chars(sb, "}"); in3_client_rpc_raw(c, sb->data, result, error); + sb_free(sb); check_last_output(); #ifdef NODESELECT_DEF in3_chain_t* chain = &c->chain; diff --git a/c/src/tools/recorder/recorder.c b/c/src/tools/recorder/recorder.c index c83102352..9d895c141 100644 --- a/c/src/tools/recorder/recorder.c +++ b/c/src/tools/recorder/recorder.c @@ -14,6 +14,20 @@ typedef struct recorder_entry { } recorder_entry_t; +typedef struct ptr { + void* ptr; + struct ptr* next; +} ptr_t; + +static ptr_t* global_ptr = NULL; +void* add_global(void* ptr) { + ptr_t* p = _malloc(sizeof(ptr_t)); + p->next = global_ptr; + p->ptr = ptr; + global_ptr = p; + return ptr; +} + typedef struct { in3_plugin_act_fn transport; FILE* f; @@ -60,12 +74,12 @@ static recorder_entry_t* read_one_entry() { continue; } if (!entry) { - entry = _calloc(sizeof(recorder_entry_t), 1); + entry = add_global(_calloc(sizeof(recorder_entry_t), 1)); char* ptr = strtok(buffer + 3, " "); entry->name = _strdupn(ptr, -1); while ((ptr = strtok(NULL, " "))) { entry->args = entry->argl ? _realloc(entry->args, sizeof(char*) * (entry->argl + 1), sizeof(char*) * entry->argl) : _malloc(sizeof(char*)); - entry->args[entry->argl++] = _strdupn(ptr, -1); + entry->args[entry->argl++] = add_global(_strdupn(ptr, -1)); } } else From 282697ada7c2f1e36a390dec48673b748702cf5c Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Wed, 18 Aug 2021 16:59:55 +0200 Subject: [PATCH 018/101] fixed memoryleak --- c/src/core/client/request.c | 5 ++++- c/src/core/util/scache.c | 2 +- c/src/core/util/scache.h | 13 +++++++------ c/src/verifier/eth1/basic/sign_tx.c | 4 +++- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/c/src/core/client/request.c b/c/src/core/client/request.c index 5c14f93d9..ed272125f 100644 --- a/c/src/core/client/request.c +++ b/c/src/core/client/request.c @@ -401,7 +401,10 @@ in3_ret_t req_send_sub_request(in3_req_t* parent, char* method, char* params, ch sprintf(req, "{\"method\":\"%s\",\"params\":[%s]}", method, params); } ctx = req_new(parent->client, req); - if (!ctx) return req_set_error(parent, "Invalid request!", IN3_ERPC); + if (!ctx) { + if (use_cache && req) _free(req); + return req_set_error(parent, "Invalid request!", IN3_ERPC); + } if (child) *child = ctx; // inherit cache-entries diff --git a/c/src/core/util/scache.c b/c/src/core/util/scache.c index c1efe8527..0457ec26b 100644 --- a/c/src/core/util/scache.c +++ b/c/src/core/util/scache.c @@ -51,7 +51,7 @@ void in3_cache_free(cache_entry_t* cache, bool is_external) { else _free(cache->key.data); } - if (cache->props & CACHE_PROP_MUST_FREE && ((cache->props & CACHE_PROP_ONLY_EXTERNAL) == 0 || is_external)) + if (cache->props & CACHE_PROP_MUST_FREE && ((cache->props & CACHE_PROP_ONLY_EXTERNAL) == 0 || is_external) && ((cache->props & CACHE_PROP_ONLY_NOT_EXTERNAL) == 0 || !is_external)) _free(cache->value.data); p = cache; cache = cache->next; diff --git a/c/src/core/util/scache.h b/c/src/core/util/scache.h index d6024f7d8..deeb17d21 100644 --- a/c/src/core/util/scache.h +++ b/c/src/core/util/scache.h @@ -50,12 +50,13 @@ extern "C" { #include typedef enum cache_props { - CACHE_PROP_MUST_FREE = 0x1, /**< indicates the content must be freed*/ - CACHE_PROP_SRC_REQ = 0x2, /**< the value holds the src-request */ - CACHE_PROP_ONLY_EXTERNAL = 0x4, /**< should only be freed if the context is external */ - CACHE_PROP_JSON = 0x8, /**< indicates the content is a json_ctxt and must be freed as such*/ - CACHE_PROP_INHERIT = 0x10, /**< indicates the content will be inherited when creating sub_request*/ - CACHE_PROP_PAYMENT = 0x80 /**< This cache-entry is a payment.data */ + CACHE_PROP_MUST_FREE = 0x1, /**< indicates the content must be freed*/ + CACHE_PROP_SRC_REQ = 0x2, /**< the value holds the src-request */ + CACHE_PROP_ONLY_EXTERNAL = 0x4, /**< should only be freed if the context is external */ + CACHE_PROP_ONLY_NOT_EXTERNAL = 0x20, /**< should only be freed if the context is not external */ + CACHE_PROP_JSON = 0x8, /**< indicates the content is a json_ctxt and must be freed as such*/ + CACHE_PROP_INHERIT = 0x10, /**< indicates the content will be inherited when creating sub_request*/ + CACHE_PROP_PAYMENT = 0x80 /**< This cache-entry is a payment.data */ } cache_props_t; /** * represents a single cache entry in a linked list. diff --git a/c/src/verifier/eth1/basic/sign_tx.c b/c/src/verifier/eth1/basic/sign_tx.c index 8bdfee9b1..e5494cc80 100644 --- a/c/src/verifier/eth1/basic/sign_tx.c +++ b/c/src/verifier/eth1/basic/sign_tx.c @@ -402,9 +402,11 @@ in3_ret_t handle_eth_sendTransaction(in3_req_t* ctx, d_token_t* req) { json_free(ctx->request_context); // set the new RPC-Request. + char* old_req = ctx->request_context->c; ctx->request_context = parse_json(sb.data); ctx->requests[0] = ctx->request_context->result; - in3_cache_add_ptr(&ctx->cache, sb.data)->props = CACHE_PROP_MUST_FREE | CACHE_PROP_ONLY_EXTERNAL; // we add the request-string to the cache, to make sure the request-string will be cleaned afterwards + in3_cache_add_ptr(&ctx->cache, sb.data)->props = CACHE_PROP_MUST_FREE | CACHE_PROP_ONLY_EXTERNAL; // we add the request-string to the cache, to make sure the request-string will be cleaned afterwards + in3_cache_add_ptr(&ctx->cache, old_req)->props = CACHE_PROP_MUST_FREE | CACHE_PROP_ONLY_NOT_EXTERNAL; // we add the request-string to the cache, to make sure the request-string will be cleaned afterwards, butt only for subrequests return IN3_OK; } From 987a3bf1ec3e6e204a7d2f8efbcea4015cd8bafa Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Wed, 18 Aug 2021 20:23:09 +0200 Subject: [PATCH 019/101] fix freed-ptr --- c/src/verifier/eth1/basic/sign_tx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/c/src/verifier/eth1/basic/sign_tx.c b/c/src/verifier/eth1/basic/sign_tx.c index e5494cc80..990595994 100644 --- a/c/src/verifier/eth1/basic/sign_tx.c +++ b/c/src/verifier/eth1/basic/sign_tx.c @@ -392,7 +392,8 @@ in3_ret_t handle_eth_sendTransaction(in3_req_t* ctx, d_token_t* req) { if (unsigned_tx.data) _free(unsigned_tx.data);) // build the RPC-request - sb_t sb = {0}; + char* old_req = ctx->request_context->c; + sb_t sb = {0}; sb_add_rawbytes(&sb, "{ \"jsonrpc\":\"2.0\", \"method\":\"eth_sendRawTransaction\", \"params\":[\"0x", signed_tx, 0); sb_add_chars(&sb, "\"]"); sb_add_chars(&sb, "}"); @@ -402,7 +403,6 @@ in3_ret_t handle_eth_sendTransaction(in3_req_t* ctx, d_token_t* req) { json_free(ctx->request_context); // set the new RPC-Request. - char* old_req = ctx->request_context->c; ctx->request_context = parse_json(sb.data); ctx->requests[0] = ctx->request_context->result; in3_cache_add_ptr(&ctx->cache, sb.data)->props = CACHE_PROP_MUST_FREE | CACHE_PROP_ONLY_EXTERNAL; // we add the request-string to the cache, to make sure the request-string will be cleaned afterwards From 329c8de753128de8c62a98e050f83ac1b9b46ba1 Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Wed, 18 Aug 2021 20:40:00 +0200 Subject: [PATCH 020/101] fix memory issue wirth get_wei --- c/src/cmd/in3/helper.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/c/src/cmd/in3/helper.c b/c/src/cmd/in3/helper.c index 4fae1268f..697ba7d71 100644 --- a/c/src/cmd/in3/helper.c +++ b/c/src/cmd/in3/helper.c @@ -196,7 +196,9 @@ char* get_wei(char* val) { bytes32_t tmp; int s = string_val_to_bytes(val, NULL, tmp); if (s < 0) die("Invalid numeric value"); - char* res = _malloc(s * 2 + 3); + static char* res = NULL; + if (res) _free(res); + res = _malloc(s * 2 + 3); bytes_to_hex(tmp, s, res + 2); if (res[2] == '0') res++; res[0] = '0'; From dfd94b4d66972fc1a43cc08f2d2fc3c612be484a Mon Sep 17 00:00:00 2001 From: leonardotc Date: Thu, 19 Aug 2021 12:06:24 +0200 Subject: [PATCH 021/101] Fix node axios transport --- wasm/src/in3.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wasm/src/in3.js b/wasm/src/in3.js index 8fd615f44..86bd4c850 100644 --- a/wasm/src/in3.js +++ b/wasm/src/in3.js @@ -88,7 +88,7 @@ else { try { // if axios is available, we use it const axios = require('' + 'axios') - in3w.transport = (url, payload, timeout = 30000, method = "POST", headers = {}) => axios({ method: method || 'POST', url, data: JSON.parse(payload), timeout, headers: { 'Content-Type': 'application/json', 'User-Agent': 'in3 wasm ' + getVersion(), in3: 'wasm ' + getVersion(), ...headers } }) + in3w.transport = (url, payload, timeout = 30000, method = "POST", headers = {}) => axios({ method: method || 'POST', url, data: payload && JSON.parse(payload), timeout, headers: { 'Content-Type': 'application/json', 'User-Agent': 'in3 wasm ' + getVersion(), in3: 'wasm ' + getVersion(), ...headers } }) .then(res => { if (res.statusCode < 200 || res.statusCode >= 400) throw new HttpError("Invalid satus", res.status) return JSON.stringify(res.data) From f9cfa2f4e39ffc79777851e4e6c50a82aaf66ddf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20K=C3=BCchler?= Date: Mon, 23 Aug 2021 12:52:29 +0200 Subject: [PATCH 022/101] removed l2 wallet transfer --- c/src/pay/zksync/testCases.yml | 121 --------------------------------- 1 file changed, 121 deletions(-) diff --git a/c/src/pay/zksync/testCases.yml b/c/src/pay/zksync/testCases.yml index d88217403..8673130fa 100644 --- a/c/src/pay/zksync/testCases.yml +++ b/c/src/pay/zksync/testCases.yml @@ -353,127 +353,6 @@ zksync: res: - result: "sync-tx:b431fad24a0b3ccc324c09b1dd3f2484ac070d944a615e46d7b822dd9e883c02" - - - - extra: "with l2 wallet" - config: - proof: 'none' - experimental: true - rpc: "https://rinkeby-light.eth.linkpool.io" - zksync: - provider_url: "https://rinkeby-api.zksync.io/jsrpc" - sync_key: "0x49db8b7407712dc2f013fac325596e0440af21192d8dbced73aec9f8d97c8ea5" - verify_proof_method: "zk_wallet_verify_signatures" - create_proof_method: "zk_wallet_create_signatures" - musig_urls: - - null - - "https://approver.incubed.net" - wallet_deploy: - creator: "0xaa8c54c65c14f132804f0809bdbef19970673709" - master_copy: "0xc73248bb521c3331e4efedbb0560e806302024fb" - add_module: "0x846A192315882ca369125F82E64e368858663898" - master_copy_custody: "0x937c53Cad1619a996645165129620eF2853c76B0" - default_wallet: "0x537f989e56dca9a3937588fc61639f634359fc88" - default_exec: "receipt" - pk: - - "0xf5f297cd9e2f7e02944e283bc920075a98c8250ca8fe4576743b1e8e044abee9" - - "0xc720d9404dc73ad831faf6ee7a55b21b30c285279dca09cfbd0015b2f05aff9b" - - "0xb66d5d63a837364c30ed9b9b0ca717e985fb694749ae4e9e12280ccc120109b0" - wallets: - - - sync_key: "0xb87e956f29eabf3878120ce97909c4f383f18e0f49d8fe7d0626a80ec9b8925f" - address: "0x537f989e56dca9a3937588fc61639f634359fc88" - threshold: 2 - type: "l2" - signer: "0xce4a5107ecdd523876deedc1a59600bff3ea7852cd1feec1a48f89bc459ae58b" - owners: - - - roles: 7 - address: "0x0d065af76869fa17525e3b0d3f3e29d9577a4501" - - - roles: 7 - address: "0x827415a37def6e0953e6b417cfe81066e3387528" - - - roles: 1 - address: "0x937c53cad1619a996645165129620ef2853c76b0" - master_copy_custody: "0x937c53cad1619a996645165129620ef2853c76b0" - create_module: "0x846a192315882ca369125f82e64e368858663898" - master_copy: "0xc73248bb521c3331e4efedbb0560e806302024fb" - cosign_url: "https://approver.incubed.net" - rpc_url: "https://rinkeby-api.zksync.io/jsrpc" - creator: "0xaa8c54c65c14f132804f0809bdbef19970673709" - saltarg: "0xe1b8515c341dfbfaa08a440019c48a66c4523263a524bf5199e0a51f86bebccf" - codehash: "0x96657bf6bdcbffce06518530907d2d729e4659ad3bc7b5cc1f5c5567d964272c" - musig_pub_keys: "0xce4a5107ecdd523876deedc1a59600bff3ea7852cd1feec1a48f89bc459ae58b4a646591170aee46931ade1148038c4c75c3972af2281a580756a0317c19872d" - - - sync_key: "0xde4525356411a77457679b43030d964784b39a5b4a0a1a5a2a82dd4fa35289a3" - address: "0x98e0df4929d07b9e542b1cae0cd42ca4e055366d" - threshold: 2 - type: "l1l2" - owners: - - - roles: 7 - address: "0x0d065af76869fa17525e3b0d3f3e29d9577a4501" - - - roles: 7 - address: "0x827415a37def6e0953e6b417cfe81066e3387528" - - roles: 1 - address: "0x937c53cad1619a996645165129620ef2853c76b0" - creator: "0xaa8c54c65c14f132804f0809bdbef19970673709" - master_copy: "0xc73248bb521c3331e4efedbb0560e806302024fb" - master_copy_custody: "0x937c53cad1619a996645165129620ef2853c76b0" - create_module: "0x846a192315882ca369125f82e64e368858663898" - custody: "0xd95c6d04d048c6863394252da421a1165b87182a" - safetype: "IAMO Safe" - - - address: "0x8D33cAFf9b73A3EB24c83ac79bb5eD56126f284C" - type: "l1l2pk" - input: - - "0x448d2286d9d6996241ff1f87bd2e24692975cabd" - - "100000000000000000" - - "ETH" - expected_output: - type: 'Transfer' - accountId: 167067 - from: "0x8d33caff9b73a3eb24c83ac79bb5ed56126f284c" - to: "0x448d2286d9d6996241ff1f87bd2e24692975cabd" - token: 0 - tokenId: 0 - amount: "100000000000000000" - fee: "30300000000000" - validFrom: 0 - validUntil: 4294967295 - nonce: 3 - txHash: "sync-tx:b431fad24a0b3ccc324c09b1dd3f2484ac070d944a615e46d7b822dd9e883c02" - mockedResponses: - - account_info: - req: - - - method: "account_info" - params: - - "0x537f989e56dca9a3937588fc61639f634359fc88" - res: - - - result: - address: "0x537f989e56dca9a3937588fc61639f634359fc88" - id: "189462" - depositing: - balances: {} - committed: - balances: - ETH: "100000000000000000" - nfts: {} - mintedNfts: {} - nonce: 0 - pubKeyHash: "sync:0000000000000000000000000000000000000000" - verified: - balances: {} - nfts: {} - mintedNfts: {} - nonce: 0 - pubKeyHash: "sync:0000000000000000000000000000000000000000" - - zksync_deposit: config: From 9e818f47d05776e4e2456c79ee4a290a70a40168 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20K=C3=BCchler?= Date: Tue, 24 Aug 2021 09:06:05 +0200 Subject: [PATCH 023/101] fixed zksync_set_key test-data --- c/src/pay/zksync/testCases.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/c/src/pay/zksync/testCases.yml b/c/src/pay/zksync/testCases.yml index 8673130fa..ff2ea3f1a 100644 --- a/c/src/pay/zksync/testCases.yml +++ b/c/src/pay/zksync/testCases.yml @@ -192,8 +192,7 @@ zksync: method: "get_tx_fee" params: - - ChangePubKey: - onchainPubkeyAuth: false + ChangePubKey: "ECDSA" - "0x8d33caff9b73a3eb24c83ac79bb5ed56126f284c" - "ETH" res: @@ -205,8 +204,7 @@ zksync: gasPriceWei: 1000000000 gasFee: 34060000000000 feeType: - ChangePubKey: - onchainPubkeyAuth: false + ChangePubKey: "ECDSA" - tx_submit: req: - From 5a8e9de2ac86ef6035b9715f8040fe98594d69fa Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Tue, 24 Aug 2021 10:20:10 +0200 Subject: [PATCH 024/101] change default gas from 30k to 40k --- c/src/verifier/eth1/basic/sign_tx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/c/src/verifier/eth1/basic/sign_tx.c b/c/src/verifier/eth1/basic/sign_tx.c index 8bdfee9b1..5cdf1a911 100644 --- a/c/src/verifier/eth1/basic/sign_tx.c +++ b/c/src/verifier/eth1/basic/sign_tx.c @@ -237,8 +237,8 @@ in3_ret_t eth_prepare_unsigned_tx(d_token_t* tx, in3_req_t* ctx, bytes_t* dst, s address_t from; // read the values - bytes_t gas_limit = d_get(tx, K_GAS) ? get(tx, K_GAS) : (d_get(tx, K_GAS_LIMIT) ? get(tx, K_GAS_LIMIT) : bytes((uint8_t*) "\x75\x30", 2)), - to = getl(tx, K_TO, 20), + bytes_t gas_limit = d_get(tx, K_GAS) ? get(tx, K_GAS) : (d_get(tx, K_GAS_LIMIT) ? get(tx, K_GAS_LIMIT) : bytes((uint8_t*) "\x9c\x40", 2)), // default: 40000 gas + to = getl(tx, K_TO, 20), value = get(tx, K_VALUE), data = get(tx, K_DATA), nonce = get(tx, K_NONCE), From 5c22ff9da99505f9b9474f6da09c23e3c0b333ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20K=C3=BCchler?= Date: Tue, 24 Aug 2021 10:42:14 +0200 Subject: [PATCH 025/101] fixed sendTransaction and sendTransactionAndWait testdata --- c/src/verifier/eth1/basic/testCases.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/c/src/verifier/eth1/basic/testCases.yml b/c/src/verifier/eth1/basic/testCases.yml index 8f0ee9833..153a2849d 100644 --- a/c/src/verifier/eth1/basic/testCases.yml +++ b/c/src/verifier/eth1/basic/testCases.yml @@ -502,6 +502,7 @@ eth: data: "0x4faa8a2600000000000000000000000000a329c0648769a73afac7f9381e08fb43dbea72" nonce: 31 gasPrice: 1000000000 + gas: 85597 expected_output: "0x02de07114d5c6e5a81e73e164b4cb623727024822318b300b93bad54482a6416" mockedResponses: - eth_sendRawTransaction: @@ -509,7 +510,7 @@ eth: - method: "eth_sendRawTransaction" params: - - "0xf8871f843b9aca0082520894123456789012345678901234567890123456789080a44faa8a2600000000000000000000000000a329c0648769a73afac7f9381e08fb43dbea722ea0d8642edc854eb204a4ab0e01cc7d91bbf70436df46d6b3c6103e49d13f0ecd97a05e3b81096a00b0703d18159cc4488b15d3d36b9dd7a125d2310ee152f6864375" + - "0xf8881f843b9aca0083014e5d94123456789012345678901234567890123456789080a44faa8a2600000000000000000000000000a329c0648769a73afac7f9381e08fb43dbea722da06605e29f890283c0b829b1b245e09b6e06c98cc4eb82c72bd61b278ccf5cd934a02f2b5e07127f0f4ef537c33cd9047238f1f773b589459f7dca0a2ce2ffcd6ff6" res: - jsonrpc: "2.0" @@ -528,6 +529,7 @@ eth: data: "0x4faa8a2600000000000000000000000000a329c0648769a73afac7f9381e08fb43dbea72" nonce: 31 gasPrice: 1000000000 + gas: 85597 expected_output: blockHash: "0xa3c56c1f5bf0fccab818b7722153737977b72b44ac10a8511ccb364da39f3582" blockNumber: "0x452c23" @@ -577,7 +579,7 @@ eth: - method: "eth_sendRawTransaction" params: - - "0xf8871f843b9aca0082520894123456789012345678901234567890123456789080a44faa8a2600000000000000000000000000a329c0648769a73afac7f9381e08fb43dbea722ea0d8642edc854eb204a4ab0e01cc7d91bbf70436df46d6b3c6103e49d13f0ecd97a05e3b81096a00b0703d18159cc4488b15d3d36b9dd7a125d2310ee152f6864375" + - "0xf8881f843b9aca0083014e5d94123456789012345678901234567890123456789080a44faa8a2600000000000000000000000000a329c0648769a73afac7f9381e08fb43dbea722da06605e29f890283c0b829b1b245e09b6e06c98cc4eb82c72bd61b278ccf5cd934a02f2b5e07127f0f4ef537c33cd9047238f1f773b589459f7dca0a2ce2ffcd6ff6" res: - jsonrpc: "2.0" From f2aa2622130b7971f166a73c108847cf530909ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20K=C3=BCchler?= Date: Tue, 24 Aug 2021 10:43:08 +0200 Subject: [PATCH 026/101] fixed preapreTx test-data --- c/src/api/eth1/testCases.yml | 82 ++++++++++++++++++++++++------------ 1 file changed, 55 insertions(+), 27 deletions(-) diff --git a/c/src/api/eth1/testCases.yml b/c/src/api/eth1/testCases.yml index 4ebca0d96..3e52421a4 100644 --- a/c/src/api/eth1/testCases.yml +++ b/c/src/api/eth1/testCases.yml @@ -65,33 +65,61 @@ account: address: "0xf68a4703314e9a9cf65be688bd6d9b3b34594ab4" in3_prepareTx: - config: - proof: 'none' - input: - - to: "0x63f666a23cbd135a91187499b5cc51d589c302a0" - value: "0x100000000" - from: "0xc2b2f4ad0d234b8c135c39eea8409b448e5e496f" - expected_output: "0xe480808252089463f666a23cbd135a91187499b5cc51d589c302a085010000000080018080" - mockedResponses: - - eth_getTransactionCount: - req: + - + config: + proof: 'none' + input: + - to: "0x63f666a23cbd135a91187499b5cc51d589c302a0" + value: "0x100000000" + from: "0xc2b2f4ad0d234b8c135c39eea8409b448e5e496f" + expected_output: "0xe48080829c409463f666a23cbd135a91187499b5cc51d589c302a085010000000080018080" + mockedResponses: + - eth_getTransactionCount: + req: + - + method: "eth_getTransactionCount" + params: + - "0xc2b2f4ad0d234b8c135c39eea8409b448e5e496f" + - "latest" + res: + - + result: "0x0" + - eth_gasPrice: + req: - - method: "eth_getTransactionCount" - params: - - "0xc2b2f4ad0d234b8c135c39eea8409b448e5e496f" - - "latest" - res: - - - result: "0x0" - - eth_gasPrice: - req: - - - method: "eth_gasPrice" - params: [] - res: - - - result: "0x0" - + method: "eth_gasPrice" + params: [] + res: + - + result: "0x0" + - + config: + proof: 'none' + input: + - to: "0x63f666a23cbd135a91187499b5cc51d589c302a0" + value: "0x100000000" + from: "0xc2b2f4ad0d234b8c135c39eea8409b448e5e496f" + gas: 21000 + expected_output: "0xe480808252089463f666a23cbd135a91187499b5cc51d589c302a085010000000080018080" + mockedResponses: + - eth_getTransactionCount: + req: + - + method: "eth_getTransactionCount" + params: + - "0xc2b2f4ad0d234b8c135c39eea8409b448e5e496f" + - "latest" + res: + - + result: "0x0" + - eth_gasPrice: + req: + - + method: "eth_gasPrice" + params: [] + res: + - + result: "0x0" in3_signTx: config: proof: "none" @@ -163,6 +191,6 @@ account: value: "15023483000000000" gasPrice: 1000000000 nonce: 32 - expected_output: "0xf86a20843b9aca00825208942c055df8d095a98099dc8942510a65d51480840e87355fc737810e00802da0fd2f892a7d154aa699ead599152d93674765eef4e6c384ffbc50db394ec3e3cea055ce9aee6e61256f7efaa9c714e4c342e21074d900f1d8399be720c56cc5f415" + expected_output: "0xf86a20843b9aca00829c40942c055df8d095a98099dc8942510a65d51480840e87355fc737810e00802ea038448f7f8591b29e97694ae8c317de840fb2e7b178714fd3d102ed082682c639a04ab7da09a2e7acb717c53c7a610c63ea9e703d483603abd066f9ada4adf88c98" From caa89e7f05f7bd6c59cf5b755d4e0527c36f03f5 Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Wed, 25 Aug 2021 11:55:59 +0200 Subject: [PATCH 027/101] fix relative path --- c/test/util/transport.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/c/test/util/transport.c b/c/test/util/transport.c index 9955cc55c..495db9aed 100644 --- a/c/test/util/transport.c +++ b/c/test/util/transport.c @@ -1,9 +1,9 @@ #include "transport.h" #include "../../src/core/client/keys.h" #include "../../src/core/util/data.h" +#include "../../src/nodeselect/full/cache.h" +#include "../../src/nodeselect/full/nodelist.h" #include "../test_utils.h" -#include "nodeselect/full/cache.h" -#include "nodeselect/full/nodelist.h" #include #include #define MOCK_PATH TESTDATA_DIR "/mock/%s.json" From 61875dfadb33053fb7565873772366279ee9184a Mon Sep 17 00:00:00 2001 From: leonardotc Date: Wed, 25 Aug 2021 12:15:21 +0200 Subject: [PATCH 028/101] Fix axios status verification on wasm transport --- wasm/src/in3.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wasm/src/in3.js b/wasm/src/in3.js index 86bd4c850..afbfcf2ef 100644 --- a/wasm/src/in3.js +++ b/wasm/src/in3.js @@ -90,7 +90,7 @@ else { const axios = require('' + 'axios') in3w.transport = (url, payload, timeout = 30000, method = "POST", headers = {}) => axios({ method: method || 'POST', url, data: payload && JSON.parse(payload), timeout, headers: { 'Content-Type': 'application/json', 'User-Agent': 'in3 wasm ' + getVersion(), in3: 'wasm ' + getVersion(), ...headers } }) .then(res => { - if (res.statusCode < 200 || res.statusCode >= 400) throw new HttpError("Invalid satus", res.status) + if (res.status < 200 || res.status >= 400) throw new HttpError("Invalid satus", res.status) return JSON.stringify(res.data) }) } catch (xx) { From c66862af706081ea6d59e79aba6186d5180a5c75 Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Wed, 25 Aug 2021 13:25:51 +0200 Subject: [PATCH 029/101] fix return type --- c/src/api/eth1/rpc.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/c/src/api/eth1/rpc.yml b/c/src/api/eth1/rpc.yml index c08c33c9d..7e4e502e9 100644 --- a/c/src/api/eth1/rpc.yml +++ b/c/src/api/eth1/rpc.yml @@ -154,6 +154,7 @@ utils: default: eth result: descr: the value in wei as hex. + type: uint256 example: request: - "20.0009123" From bc8327d764dc6b6c900eca746b938e51ebbcf7ea Mon Sep 17 00:00:00 2001 From: chirag-parmar Date: Sun, 29 Aug 2021 18:27:40 +0200 Subject: [PATCH 030/101] Add vade to runner --- c/test/runner.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/c/test/runner.c b/c/test/runner.c index e1abedd7a..433966b2a 100644 --- a/c/test/runner.c +++ b/c/test/runner.c @@ -455,6 +455,10 @@ int runRequests(char** names, int test_index) { int main(int argc, char* argv[]) { use_color = 1; in3_log_set_level(LOG_INFO); + + in3_ret_t in3_register_vade (in3_t*); + in3_register_default(in3_register_vade); + in3_register_default(in3_register_eth_full); in3_register_default(in3_register_eth_api); in3_register_default(in3_register_ipfs); From 3fb2282613d21c111fe451a3f9032eb3b5b2e355 Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Tue, 31 Aug 2021 16:34:33 +0200 Subject: [PATCH 031/101] fix vade-tests --- c/test/runner.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/c/test/runner.c b/c/test/runner.c index 433966b2a..bd9ad7f3b 100644 --- a/c/test/runner.c +++ b/c/test/runner.c @@ -455,9 +455,10 @@ int runRequests(char** names, int test_index) { int main(int argc, char* argv[]) { use_color = 1; in3_log_set_level(LOG_INFO); - - in3_ret_t in3_register_vade (in3_t*); +#ifdef VADE + in3_ret_t in3_register_vade(in3_t*); in3_register_default(in3_register_vade); +#endif in3_register_default(in3_register_eth_full); in3_register_default(in3_register_eth_api); From fc2d3edc7e87822d82bfbded76924e5addc55f24 Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Tue, 31 Aug 2021 17:54:50 +0200 Subject: [PATCH 032/101] update alias handling --- scripts/generator/generate.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/generator/generate.js b/scripts/generator/generate.js index 0e7b8b8cf..c17202986 100755 --- a/scripts/generator/generate.js +++ b/scripts/generator/generate.js @@ -86,6 +86,8 @@ function print_object(def, pad, useNum, doc, pre) { for (const prop of Object.keys(def)) { let s = pad + (useNum ? ((i++) + '.') : '*') + ' **' + prop + '**' const p = def[prop] + while (typeof p.type == 'string' && typeof (types[p.type]) === 'string') p.type = types[p.type] + const pt = getType(p.type, types) if (p.type) s += ' : ' + typeName(p, true) if (p.optional) s += ' *(optional)*' From 38c38782401284f69e52b15d3d7b51018dbc750e Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Tue, 31 Aug 2021 20:06:07 +0200 Subject: [PATCH 033/101] fix compiler warnings --- c/src/third-party/crypto/CMakeLists.txt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/c/src/third-party/crypto/CMakeLists.txt b/c/src/third-party/crypto/CMakeLists.txt index f3d41f5e9..f1c4c2006 100644 --- a/c/src/third-party/crypto/CMakeLists.txt +++ b/c/src/third-party/crypto/CMakeLists.txt @@ -57,10 +57,16 @@ set(CRYPTO_SRC if (NOT ESP_IDF) set(CRYPTO_SRC ${CRYPTO_SRC} hmac.c) endif() - +if (WASM) + set (CMAKE_C_FLAGS "$CMAKE_C_FLAGS -Wno-null-pointer-subtraction") + set (CMAKE_CXX_FLAGS "$CMAKE_CXX_FLAGS -Wno-null-pointer-subtraction") +endif() add_static_library( NAME crypto SOURCES ${CRYPTO_SRC} ) + + + From b5a5c354da3406febf11b371aacf08a0fa969d46 Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Tue, 31 Aug 2021 20:13:01 +0200 Subject: [PATCH 034/101] fix cmake-options --- c/compiler.cmake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/c/compiler.cmake b/c/compiler.cmake index fe8e3d22c..e4e966a1c 100644 --- a/c/compiler.cmake +++ b/c/compiler.cmake @@ -10,8 +10,8 @@ else(MSVC) endif() endif(MSVC) if (WASM) - set (CMAKE_C_FLAGS "-Wall -funsigned-char -Wextra -std=c99 -Wno-unused-function") - set (CMAKE_CXX_FLAGS "-Wall -funsigned-char -Wextra -std=c99 -Wno-unused-function -D__FILENAME__='\"$(subst ${CMAKE_SOURCE_DIR}/,,$(abspath $<))\"'") + set (CMAKE_C_FLAGS "-Wall -funsigned-char -Wextra -std=c99 -Wno-unused-function -Wno-null-pointer-subtraction") + set (CMAKE_CXX_FLAGS "-Wall -funsigned-char -Wextra -std=c99 -Wno-unused-function -Wno-null-pointer-subtraction -D__FILENAME__='\"$(subst ${CMAKE_SOURCE_DIR}/,,$(abspath $<))\"'") if (CMAKE_BUILD_TYPE MATCHES Debug) set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined,address -fsanitize-minimal-runtime") set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined,address -fsanitize-minimal-runtime") @@ -25,7 +25,7 @@ if(MSVC) elseif(WASM) set (CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wno-missing-braces") else() - set (CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} -Werror=vla -Wno-missing-braces") + set (CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} -Werror=vla -Wno-missing-braces -Wno-null-pointer-subtraction") endif() set_property(GLOBAL PROPERTY C_STANDARD 99) From e93dd08a7d346cb214764f4f75ef9b6471de1a0a Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Tue, 31 Aug 2021 20:13:20 +0200 Subject: [PATCH 035/101] remove cmake-options --- c/src/third-party/crypto/CMakeLists.txt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/c/src/third-party/crypto/CMakeLists.txt b/c/src/third-party/crypto/CMakeLists.txt index f1c4c2006..50871ed60 100644 --- a/c/src/third-party/crypto/CMakeLists.txt +++ b/c/src/third-party/crypto/CMakeLists.txt @@ -57,10 +57,7 @@ set(CRYPTO_SRC if (NOT ESP_IDF) set(CRYPTO_SRC ${CRYPTO_SRC} hmac.c) endif() -if (WASM) - set (CMAKE_C_FLAGS "$CMAKE_C_FLAGS -Wno-null-pointer-subtraction") - set (CMAKE_CXX_FLAGS "$CMAKE_CXX_FLAGS -Wno-null-pointer-subtraction") -endif() + add_static_library( NAME crypto From 6a77dd0a209b52f0891b06290b104f42c6d66bfc Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Fri, 3 Sep 2021 09:37:11 +0200 Subject: [PATCH 036/101] fix param-checks --- c/compiler.cmake | 4 +- c/src/core/util/debug.h | 145 +-------------------------------------- c/src/core/util/params.h | 135 +++++++++++++++++++++++++++++++----- 3 files changed, 122 insertions(+), 162 deletions(-) diff --git a/c/compiler.cmake b/c/compiler.cmake index e4e966a1c..4a14c45de 100644 --- a/c/compiler.cmake +++ b/c/compiler.cmake @@ -23,9 +23,9 @@ endif(WASM) if(MSVC) set (CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} /W4 /WX") elseif(WASM) - set (CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wno-missing-braces") + set (CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wno-missing-braces -Wno-null-pointer-subtraction") else() - set (CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} -Werror=vla -Wno-missing-braces -Wno-null-pointer-subtraction") + set (CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} -Werror=vla -Wno-missing-braces") endif() set_property(GLOBAL PROPERTY C_STANDARD 99) diff --git a/c/src/core/util/debug.h b/c/src/core/util/debug.h index 5bd998720..4cb5ad19c 100644 --- a/c/src/core/util/debug.h +++ b/c/src/core/util/debug.h @@ -37,8 +37,8 @@ * logs debug data only if the DEBUG-flag is set. * */ -#ifndef DEBUG_H -#define DEBUG_H +#ifndef IN3_DEBUG_H +#define IN3_DEBUG_H #include "params.h" #include "stringbuilder.h" @@ -146,147 +146,6 @@ static inline void add_hex(sb_t* sb, char prefix, const char* property, bytes_t sb_add_bytes(sb, NULL, &value, 1, false); } -// macros for checking params -#define CHECK_PARAMS_LEN(ctx, params, len) \ - if (d_type(params) != T_ARRAY || d_len(params) < len) return req_set_error(ctx, "arguments need to be a array with at least " #len " arguments", IN3_EINVAL); -#define CHECK_PARAM_TYPE(ctx, params, index, type) \ - if (d_type(d_get_at(params, index)) != type) return req_set_error(ctx, "argument at index " #index " must be a " #type, IN3_EINVAL); -#define CHECK_PARAM_NUMBER(ctx, params, index) \ - switch (d_type(d_get_at(params, index))) { \ - case T_INTEGER: \ - case T_BYTES: break; \ - default: return req_set_error(ctx, "argument at index " #index " must be a number", IN3_EINVAL); \ - } -#define CHECK_PARAM_ADDRESS(ctx, params, index) \ - { \ - const d_token_t* val = d_get_at(params, index); \ - if (d_type(val) != T_BYTES || val->len != 20) return req_set_error(ctx, "argument at index " #index " must be a valid address", IN3_EINVAL); \ - } -#define CHECK_PARAM_LEN(ctx, params, index, len) \ - if (d_len(d_get_at(params, index)) != len) return req_set_error(ctx, "argument at index " #index " must have a length of " #len, IN3_EINVAL); -#define CHECK_PARAM_MAX_LEN(ctx, params, index, len) \ - if (d_len(d_get_at(params, index)) > len) return req_set_error(ctx, "argument at index " #index " must be smaller than " #len, IN3_EINVAL); -#define CHECK_PARAM_MIN_LEN(ctx, params, index, len) \ - if (d_len(d_get_at(params, index)) < len) return req_set_error(ctx, "argument at index " #index " must be at least " #len, IN3_EINVAL); -#define CHECK_PARAM(ctx, params, index, cond) \ - { \ - const d_token_t* val = d_get_at(params, index); \ - if (!(cond)) return req_set_error(ctx, "argument at index " #index " must match " #cond, IN3_EINVAL); \ - } -#define TRY_PARAM_GET_BYTES(target, ctx, index, min_len, max_len) \ - { \ - const d_token_t* t = d_get_at(ctx->params, index); \ - if (d_type(t) == T_NULL) \ - target = NULL_BYTES; \ - else if (d_type(t) == T_OBJECT || d_type(t) == T_ARRAY) \ - return req_set_error(ctx->req, "Param at " #index " must be bytes!", IN3_EINVAL); \ - else { \ - target = d_to_bytes(t); \ - if (target.len < min_len) return req_set_error(ctx->req, "Param at " #index " must have at least a length of " #min_len, IN3_EINVAL); \ - if (max_len && target.len > max_len) return req_set_error(ctx->req, "Param at " #index " must have max " #max_len "bytes", IN3_EINVAL); \ - } \ - } -#define TRY_PARAM_GET_REQUIRED_BYTES(target, ctx, index, min_len, max_len) \ - { \ - target = d_to_bytes(d_get_at(ctx->params, index)); \ - if (!target.data) return req_set_error(ctx->req, "Param at " #index " must be bytes!", IN3_EINVAL); \ - if (target.len < min_len) return req_set_error(ctx->req, "Param at " #index " must have at least a length of " #min_len, IN3_EINVAL); \ - if (max_len && target.len > max_len) return req_set_error(ctx->req, "Param at " #index " must have max " #max_len "bytes", IN3_EINVAL); \ - } - -#define TRY_PARAM_GET_INT(target, ctx, index, def) \ - { \ - const d_token_t* t = d_get_at(ctx->params, index); \ - if (d_type(t) == T_NULL) \ - target = def; \ - else if (d_type(t) != T_INTEGER) \ - return req_set_error(ctx->req, "Param at " #index " must be an integer!", IN3_EINVAL); \ - else \ - target = d_int(t); \ - } -#define TRY_PARAM_GET_BOOL(target, ctx, index, def) \ - { \ - const d_token_t* t = d_get_at(ctx->params, index); \ - if (d_type(t) == T_NULL) \ - target = def; \ - else if (d_type(t) != T_BOOLEAN) \ - return req_set_error(ctx->req, "Param at " #index " must be an true or false!", IN3_EINVAL); \ - else \ - target = d_int(t); \ - } - -#define TRY_PARAM_GET_ADDRESS(target, ctx, index, def) \ - { \ - const d_token_t* t = d_get_at(ctx->params, index); \ - if (d_type(t) == T_NULL) \ - target = def; \ - else if (d_type(t) != T_BYTES || d_len(t) != 20) \ - return req_set_error(ctx->req, "Param at " #index " must be a valid address!", IN3_EINVAL); \ - else \ - target = t->data; \ - } - -#define TRY_PARAM_GET_REQUIRED_ADDRESS(target, ctx, index) \ - { \ - const d_token_t* t = d_get_at(ctx->params, index); \ - if (d_type(t) != T_BYTES || d_len(t) != 20) \ - return req_set_error(ctx->req, "Param at " #index " must be a valid address!", IN3_EINVAL); \ - else \ - target = t->data; \ - } - -#define TRY_PARAM_GET_STRING(target, ctx, index, def) \ - { \ - const d_token_t* t = d_get_at(ctx->params, index); \ - if (d_type(t) == T_NULL) \ - target = def; \ - else if (d_type(t) != T_STRING) \ - return req_set_error(ctx->req, "Param at " #index " must be a valid string!", IN3_EINVAL); \ - else \ - target = d_string(t); \ - } - -#define TRY_PARAM_GET_REQUIRED_STRING(target, ctx, index) \ - { \ - const d_token_t* t = d_get_at(ctx->params, index); \ - if (d_type(t) != T_STRING) \ - return req_set_error(ctx->req, "Param at " #index " must be a valid string!", IN3_EINVAL); \ - else \ - target = d_string(t); \ - } - -#define TRY_PARAM_GET_OBJECT(target, ctx, index) \ - { \ - target = d_get_at(ctx->params, index); \ - if (d_type(target) == T_NULL) \ - target = NULL; \ - else if (d_type(target) != T_OBJECT) \ - return req_set_error(ctx->req, "Param at " #index " must be a valid object!", IN3_EINVAL); \ - } - -#define TRY_PARAM_GET_REQUIRED_OBJECT(target, ctx, index) \ - { \ - target = d_get_at(ctx->params, index); \ - if (d_type(target) != T_OBJECT) \ - return req_set_error(ctx->req, "Param at " #index " must be a valid object!", IN3_EINVAL); \ - } - -#define TRY_PARAM_GET_ARRAY(target, ctx, index) \ - { \ - target = d_get_at(ctx->params, index); \ - if (d_type(target) == T_NULL) \ - target = NULL; \ - else if (d_type(target) != T_ARRAY) \ - return req_set_error(ctx->req, "Param at " #index " must be a valid array!", IN3_EINVAL); \ - } - -#define TRY_PARAM_GET_REQUIRED_ARRAY(target, ctx, index) \ - { \ - target = d_get_at(ctx->params, index); \ - if (d_type(target) != T_ARRAY) \ - return req_set_error(ctx->req, "Param at " #index " must be a valid array!", IN3_EINVAL); \ - } - /** used for exeuting a function based on the name. This macro will return if the name matches. */ #endif /* DEBUG_H */ \ No newline at end of file diff --git a/c/src/core/util/params.h b/c/src/core/util/params.h index f2bb8fcfa..da94fa154 100644 --- a/c/src/core/util/params.h +++ b/c/src/core/util/params.h @@ -32,24 +32,73 @@ const d_token_t* val = d_get_at(params, index); \ if (!(cond)) return req_set_error(ctx, "argument at index " #index " must match " #cond, IN3_EINVAL); \ } +#define TRY_PARAM_GET_BYTES(target, ctx, index, min_len, max_len) \ + { \ + const d_token_t* t = d_get_at(ctx->params, index); \ + if (d_type(t) == T_NULL) \ + target = NULL_BYTES; \ + else if (d_type(t) == T_OBJECT || d_type(t) == T_ARRAY) \ + return req_set_error(ctx->req, "Param at " #index " must be bytes!", IN3_EINVAL); \ + else { \ + target = d_to_bytes(t); \ + if (target.len < min_len) return req_set_error(ctx->req, "Param at " #index " must have at least a length of " #min_len, IN3_EINVAL); \ + if (max_len && target.len > max_len) return req_set_error(ctx->req, "Param at " #index " must have max " #max_len "bytes", IN3_EINVAL); \ + } \ + } +#define TRY_PARAM_GET_REQUIRED_BYTES(target, ctx, index, min_len, max_len) \ + { \ + target = d_to_bytes(d_get_at(ctx->params, index)); \ + if (!target.data) return req_set_error(ctx->req, "Param at " #index " must be bytes!", IN3_EINVAL); \ + if (target.len < min_len) return req_set_error(ctx->req, "Param at " #index " must have at least a length of " #min_len, IN3_EINVAL); \ + if (max_len && target.len > max_len) return req_set_error(ctx->req, "Param at " #index " must have max " #max_len "bytes", IN3_EINVAL); \ + } + +#define TRY_PARAM_GET_INT(target, ctx, index, def) \ + { \ + const d_token_t* t = d_get_at(ctx->params, index); \ + if (d_type(t) == T_NULL) \ + target = def; \ + else if (d_type(t) != T_INTEGER) \ + return req_set_error(ctx->req, "Param at " #index " must be an integer value!", IN3_EINVAL); \ + else \ + target = d_int(t); \ + } +#define TRY_PARAM_GET_REQUIRED_INT(target, ctx, index) \ + { \ + const d_token_t* t = d_get_at(ctx->params, index); \ + if (d_type(t) != T_INTEGER) \ + return req_set_error(ctx->req, "Param at " #index " must be an integer value!", IN3_EINVAL); \ + else \ + target = d_int(t); \ + } -#define TRY_PARAM_GET_INT(target, ctx, index, def) \ - { \ - const d_token_t* t = d_get_at(ctx->params, index); \ - if (d_type(t) == T_NULL) \ - target = def; \ - else if (d_type(t) != T_INTEGER) \ - return req_set_error(ctx->req, "Param at " #index " must be an integer!", IN3_EINVAL); \ - else \ - target = d_int(t); \ - } -#define TRY_PARAM_GET_REQUIRED_INT(target, ctx, index) \ - { \ - const d_token_t* t = d_get_at(ctx->params, index); \ - if (d_type(t) != T_INTEGER) \ - return req_set_error(ctx->req, "Param at " #index " must be an integer!", IN3_EINVAL); \ - else \ - target = d_int(t); \ +#define TRY_PARAM_GET_LONG(target, ctx, index, def) \ + { \ + const d_token_t* t = d_get_at(ctx->params, index); \ + if (d_type(t) == T_NULL) \ + target = def; \ + else if (d_type(t) == T_INTEGER || (d_type(t) == T_BYTES && d_len(t) <= 8)) \ + target = d_long(t); \ + else \ + return req_set_error(ctx->req, "Param at " #index " must be an long value!", IN3_EINVAL); \ + } +#define TRY_PARAM_GET_REQUIRED_LONG(target, ctx, index) \ + { \ + const d_token_t* t = d_get_at(ctx->params, index); \ + if (d_type(t) == T_INTEGER || (d_type(t) == T_BYTES && d_len(t) <= 8)) \ + target = d_long(t); \ + else \ + return req_set_error(ctx->req, "Param at " #index " must be an long value!", IN3_EINVAL); \ + } +#define TRY_PARAM_GET_BOOL(target, ctx, index, def) \ + { \ + const d_token_t* t = d_get_at(ctx->params, index); \ + if (d_type(t) == T_NULL) \ + target = def; \ + else if (d_type(t) != T_BOOLEAN) \ + return req_set_error(ctx->req, "Param at " #index " must be an true or false!", IN3_EINVAL); \ + else \ + target = d_int(t); \ } #define TRY_PARAM_GET_ADDRESS(target, ctx, index, def) \ @@ -72,4 +121,56 @@ target = t->data; \ } +#define TRY_PARAM_GET_STRING(target, ctx, index, def) \ + { \ + const d_token_t* t = d_get_at(ctx->params, index); \ + if (d_type(t) == T_NULL) \ + target = def; \ + else if (d_type(t) != T_STRING) \ + return req_set_error(ctx->req, "Param at " #index " must be a valid string!", IN3_EINVAL); \ + else \ + target = d_string(t); \ + } + +#define TRY_PARAM_GET_REQUIRED_STRING(target, ctx, index) \ + { \ + const d_token_t* t = d_get_at(ctx->params, index); \ + if (d_type(t) != T_STRING) \ + return req_set_error(ctx->req, "Param at " #index " must be a valid string!", IN3_EINVAL); \ + else \ + target = d_string(t); \ + } + +#define TRY_PARAM_GET_OBJECT(target, ctx, index) \ + { \ + target = d_get_at(ctx->params, index); \ + if (d_type(target) == T_NULL) \ + target = NULL; \ + else if (d_type(target) != T_OBJECT) \ + return req_set_error(ctx->req, "Param at " #index " must be a valid object!", IN3_EINVAL); \ + } + +#define TRY_PARAM_GET_REQUIRED_OBJECT(target, ctx, index) \ + { \ + target = d_get_at(ctx->params, index); \ + if (d_type(target) != T_OBJECT) \ + return req_set_error(ctx->req, "Param at " #index " must be a valid object!", IN3_EINVAL); \ + } + +#define TRY_PARAM_GET_ARRAY(target, ctx, index) \ + { \ + target = d_get_at(ctx->params, index); \ + if (d_type(target) == T_NULL) \ + target = NULL; \ + else if (d_type(target) != T_ARRAY) \ + return req_set_error(ctx->req, "Param at " #index " must be a valid array!", IN3_EINVAL); \ + } + +#define TRY_PARAM_GET_REQUIRED_ARRAY(target, ctx, index) \ + { \ + target = d_get_at(ctx->params, index); \ + if (d_type(target) != T_ARRAY) \ + return req_set_error(ctx->req, "Param at " #index " must be a valid array!", IN3_EINVAL); \ + } + #endif \ No newline at end of file From 27a06cb45ee2faceb66b058b497db2b730ef3030 Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Fri, 3 Sep 2021 13:05:12 +0200 Subject: [PATCH 037/101] fixing wasm --- c/compiler.cmake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/c/compiler.cmake b/c/compiler.cmake index 4a14c45de..1a2fbe3c0 100644 --- a/c/compiler.cmake +++ b/c/compiler.cmake @@ -10,8 +10,8 @@ else(MSVC) endif() endif(MSVC) if (WASM) - set (CMAKE_C_FLAGS "-Wall -funsigned-char -Wextra -std=c99 -Wno-unused-function -Wno-null-pointer-subtraction") - set (CMAKE_CXX_FLAGS "-Wall -funsigned-char -Wextra -std=c99 -Wno-unused-function -Wno-null-pointer-subtraction -D__FILENAME__='\"$(subst ${CMAKE_SOURCE_DIR}/,,$(abspath $<))\"'") + set (CMAKE_C_FLAGS "-Wall -funsigned-char -Wextra -std=c99 -Wno-unused-function -Wno-null-pointer-arithmetic") + set (CMAKE_CXX_FLAGS "-Wall -funsigned-char -Wextra -std=c99 -Wno-unused-function -Wno-null-pointer-arithmetic -D__FILENAME__='\"$(subst ${CMAKE_SOURCE_DIR}/,,$(abspath $<))\"'") if (CMAKE_BUILD_TYPE MATCHES Debug) set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined,address -fsanitize-minimal-runtime") set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined,address -fsanitize-minimal-runtime") @@ -23,7 +23,7 @@ endif(WASM) if(MSVC) set (CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} /W4 /WX") elseif(WASM) - set (CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wno-missing-braces -Wno-null-pointer-subtraction") + set (CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wno-missing-braces -Wno-null-pointer-arithmetic") else() set (CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} -Werror=vla -Wno-missing-braces") endif() From 5ee61a5ef04ae3cf45d3a449f5412b6fb4fd8a6a Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Fri, 3 Sep 2021 23:08:00 +0200 Subject: [PATCH 038/101] add macro --- c/src/core/client/plugin.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/c/src/core/client/plugin.h b/c/src/core/client/plugin.h index f6412397b..4ee22f8d8 100644 --- a/c/src/core/client/plugin.h +++ b/c/src/core/client/plugin.h @@ -562,6 +562,20 @@ typedef struct { } \ } +/** + * sets the string as taken from the given property to the target and raises an error if the len does not fit. + */ +#define CNF_SET_STRING(dst, token, property) \ + { \ + const d_token_t* t = d_get(token, key(property)); \ + if (d_type(t) != T_NULL && d_type(t) != T_STRING) CNF_ERROR("Invalid config for " property "!") \ + const char* tmp = d_string(t); \ + if (tmp) { \ + if (dst) _free(dst); \ + dst = _strdupn(tmp, -1); \ + } \ + } + #ifdef __cplusplus } #endif From 07b257f078178fce1e11e7f9b90d1cc3b49e8c28 Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Thu, 9 Sep 2021 09:23:42 +0200 Subject: [PATCH 039/101] change signer-interface --- wasm/src/in3.js | 4 ++-- wasm/src/in3_util.js | 12 ++++++++---- wasm/src/index.d.ts | 35 ++++++++++++++++++++++++++--------- wasm/src/wasm.c | 11 ++++++----- 4 files changed, 42 insertions(+), 20 deletions(-) diff --git a/wasm/src/in3.js b/wasm/src/in3.js index afbfcf2ef..c48a0ea92 100644 --- a/wasm/src/in3.js +++ b/wasm/src/in3.js @@ -322,10 +322,10 @@ class IN3 { switch (req.type) { case 'sign': try { - const [message, account] = Array.isArray(req.payload) ? req.payload[0].params : req.payload.params; + const [method, message, account, pl_type, meta] = Array.isArray(req.payload) ? [req.payload[0].method, ...req.payload[0].params] : [req.payload.method, ...req.payload.params]; if (!this.signer) throw new Error('no signer set to handle signing') if (!(await this.signer.canSign(account))) throw new Error('unknown account ' + account) - setResponse(req.ctx, toHex(await this.signer.sign(message, account, true, false)), 0, false) + setResponse(req.ctx, toHex(await this.signer.sign(message, account, method, pl_type, meta)), 0, false) } catch (ex) { setResponse(req.ctx, ex.message || ex, 0, ex.status || true) } diff --git a/wasm/src/in3_util.js b/wasm/src/in3_util.js index 7c963c4e7..7ca14234b 100644 --- a/wasm/src/in3_util.js +++ b/wasm/src/in3_util.js @@ -196,10 +196,14 @@ function abiEncode(sig, ...params) { } } -function ecSign(pk, data, hashMessage = true, adjustV = true) { +function ecSign(pk, data, signType) { data = toUint8Array(data) pk = toUint8Array(pk) - return toBuffer(call_buffer('ec_sign', 65, pk, hashMessage ? 1 : 0, data, data.byteLength, adjustV ? 1 : 0)) + let st = 0; + if (signType == 'ec_prefix') st = 2; + if (signType == 'ec_hash') st = 1; + + return toBuffer(call_buffer('ec_sign', 65, pk, st, data, data.byteLength, false)) } function abiDecode(sig, data) { @@ -625,10 +629,10 @@ class SimpleSigner { return !!this.accounts[toChecksumAddress(address)] } - async sign(data, account, type, ethV = true) { + async sign(data, account, sign_type, payloadType, meta) { const pk = this.accounts[toChecksumAddress(account)] if (!pk || pk.length != 32) throw new Error('Account not found for signing ' + account) - return ecSign(pk, data, type, ethV) + return ecSign(pk, data, sign_type) } diff --git a/wasm/src/index.d.ts b/wasm/src/index.d.ts index 62c20b4d4..384e7a690 100644 --- a/wasm/src/index.d.ts +++ b/wasm/src/index.d.ts @@ -612,6 +612,28 @@ export type Address = Hex */ export type Data = Hex +/** + * the type of signature to create. + * - ec_hash : the data needs to be hashed first ( using keccak) before signing + * - ec_raw : the data is the ryw value (32bytes) to sign + * - ec_prefix : the data is a message which needs to be prefixed with the EthereumSignedMessage and length to before hashing and signing + */ +export type SignType = 'ec_hash' | 'ec_prefix' | 'ec_raw' + +/** + * The type of the payload to sign + */ +export enum SignPayload { + /**< custom data to be signed*/ + PL_SIGN_ANY = 0, + /**< the payload is a ethereum-tx */ + PL_SIGN_ETHTX = 1, + /**< the payload is a BTC-Tx-Input */ + PL_SIGN_BTCTX = 2, + /**< The payload is a rlp-encoded data of a Gnosys Safe Tx */ + PL_SIGN_SAFETX = 3, +} + /** * Signature */ @@ -663,8 +685,6 @@ export type Transaction = { export declare interface Signer { - /** optiional method which allows to change the transaction-data before sending it. This can be used for redirecting it through a multisig. */ - prepareTransaction?: (client: IN3Generic, tx: Transaction) => Promise /** returns true if the account is supported (or unlocked) */ canSign(address: Address): Promise @@ -676,7 +696,7 @@ export declare interface Signer { * signing of any data. * if hashFirst is true the data should be hashed first, otherwise the data is the hash. */ - sign: (data: Hex, account: Address, hashFirst?: boolean, ethV?: boolean) => Promise + sign: (data: Hex, account: Address, sign_type: SignType, payloadType: SignPayload, meta?: any) => Promise } export declare class SimpleSigner implements Signer { @@ -689,8 +709,6 @@ export declare class SimpleSigner implements Signer, tx: Transaction) => Promise /** returns true if the account is supported (or unlocked) */ canSign(address: Address): Promise @@ -699,7 +717,7 @@ export declare class SimpleSigner implements Signer Promise + sign: (data: Hex, account: Address, sign_type: SignType, payloadType: SignPayload, meta?: any) => Promise } /** @@ -808,10 +826,9 @@ export declare interface Utils { * create a signature (65 bytes) for the given message and kexy * @param pk the private key * @param msg the message - * @param hashFirst if true the message will be hashed first (default:true), if not the message is the hash. - * @param adjustV if true (default) the v value will be adjusted by adding 27 + * @param signType the type of signature to create */ - ecSign(pk: Hex | BufferType, msg: Hex | BufferType, hashFirst?: boolean, adjustV?: boolean): BufferType + ecSign(pk: Hex | BufferType, msg: Hex | BufferType, signType: SignType): BufferType /** * takes raw signature (65 bytes) and splits it into a signature object. diff --git a/wasm/src/wasm.c b/wasm/src/wasm.c index 773296ae2..27f67f72d 100644 --- a/wasm/src/wasm.c +++ b/wasm/src/wasm.c @@ -71,7 +71,7 @@ static char* last_error = NULL; static uint32_t now() { static uint64_t time_offset = 0; if (!time_offset) time_offset = current_ms(); - return (uint32_t)(current_ms() - time_offset); + return (uint32_t) (current_ms() - time_offset); } void EMSCRIPTEN_KEEPALIVE in3_set_error(char* data) { if (last_error) free(last_error); @@ -266,7 +266,7 @@ char* EMSCRIPTEN_KEEPALIVE ctx_execute(in3_req_t* ctx) { sb_add_chars(sb, ",\"wait\":"); sb_add_int(sb, (uint64_t) request->wait); sb_add_chars(sb, ",\"payload\":"); - sb_add_chars(sb, (request->payload && strlen(request->payload))?request->payload:"null"); + sb_add_chars(sb, (request->payload && strlen(request->payload)) ? request->payload : "null"); sb_add_chars(sb, ",\"method\":\""); sb_add_chars(sb, request->method); sb_add_chars(sb, "\",\"urls\":["); @@ -526,12 +526,13 @@ uint8_t* EMSCRIPTEN_KEEPALIVE ec_sign(bytes32_t pk, d_signature_type_t type, uin int error = -1; switch (type) { case SIGN_EC_PREFIX: { - bytes32_t hash; + bytes32_t hash; struct SHA3_CTX kctx; sha3_256_Init(&kctx); - const char* PREFIX = "\x19" "Ethereum Signed Message:\n"; + const char* PREFIX = "\x19" + "Ethereum Signed Message:\n"; sha3_Update(&kctx, (uint8_t*) PREFIX, strlen(PREFIX)); - sha3_Update(&kctx, hash, sprintf((char*)hash,"%d", len) ); + sha3_Update(&kctx, hash, sprintf((char*) hash, "%d", len)); if (len) sha3_Update(&kctx, data, len); keccak_Final(&kctx, hash); error = ecdsa_sign_digest(&secp256k1, pk, hash, dst, dst + 64, NULL); From 6be03fa101c8ce74253b02b292fd23d996188797 Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Thu, 9 Sep 2021 21:51:16 +0200 Subject: [PATCH 040/101] fix js signing tests --- wasm/src/in3_util.js | 6 +++--- wasm/src/modules/eth.js | 4 ++-- wasm/test/package.json | 3 --- wasm/test/testEthApi.js | 12 ++++++------ wasm/test/testUtil.js | 12 ++++++------ 5 files changed, 17 insertions(+), 20 deletions(-) diff --git a/wasm/src/in3_util.js b/wasm/src/in3_util.js index 7ca14234b..673bdb184 100644 --- a/wasm/src/in3_util.js +++ b/wasm/src/in3_util.js @@ -200,8 +200,8 @@ function ecSign(pk, data, signType) { data = toUint8Array(data) pk = toUint8Array(pk) let st = 0; - if (signType == 'ec_prefix') st = 2; - if (signType == 'ec_hash') st = 1; + if (signType && signType.endsWith('prefix')) st = 2; + if (signType && signType.endsWith('hash')) st = 1; return toBuffer(call_buffer('ec_sign', 65, pk, st, data, data.byteLength, false)) } @@ -632,7 +632,7 @@ class SimpleSigner { async sign(data, account, sign_type, payloadType, meta) { const pk = this.accounts[toChecksumAddress(account)] if (!pk || pk.length != 32) throw new Error('Account not found for signing ' + account) - return ecSign(pk, data, sign_type) + return ecSign(pk, data, sign_type || 'hash') } diff --git a/wasm/src/modules/eth.js b/wasm/src/modules/eth.js index b91993836..b21da9af5 100644 --- a/wasm/src/modules/eth.js +++ b/wasm/src/modules/eth.js @@ -406,9 +406,9 @@ class EthAPI { } if (account && account.length == 66) // use direct pk - s.signature = toHex(ecSign(account, s.messageHash, false)) + s.signature = toHex(ecSign(account, s.messageHash, 'raw')) else if (this.client.signer && await this.client.signer.canSign(account)) // use signer - s.signature = toHex(await this.client.signer.sign(s.messageHash, account, false, true)) + s.signature = toHex(await this.client.signer.sign(s.messageHash, account, 'raw')) else throw new Error('no signer found to sign for this account') return { ...splitSignature(s.signature, message, false), ...s, messageHash: toHex(s.messageHash) } } diff --git a/wasm/test/package.json b/wasm/test/package.json index 780218146..5c86f36cd 100644 --- a/wasm/test/package.json +++ b/wasm/test/package.json @@ -35,9 +35,6 @@ }, "homepage": "https://github.com/blockchainsllc/in3#readme", "devDependencies": { - "@babel/core": "^7.0.0-beta.49", - "@babel/preset-env": "^7.0.0-beta.49", - "@babel/preset-es2015": "^7.0.0-beta.53", "chai": "^4.1.2", "chai-spies": "^1.0.0", "handlebars": ">=4.1.2", diff --git a/wasm/test/testEthApi.js b/wasm/test/testEthApi.js index 7a5f188ba..02085cacc 100644 --- a/wasm/test/testEthApi.js +++ b/wasm/test/testEthApi.js @@ -111,10 +111,10 @@ describe('EthAPI-Tests', () => { it('eth.sign()', async () => { const pk = '0x889dbed9450f7a4b68e0732ccb7cd016dab158e6946d16158f2736fda1143ca6' const msg = '0x9fa034abf05bd334e60d92da257eb3d66dd3767bba9a1d7a7575533eb0977465' - assert.equal(IN3.util.toHex(IN3.util.ecSign(pk, msg, false)) - , '0xf596af3336ac65b01ff4b9c632bc8af8043f8c11ae4de626c74d834412cb5a234783c14807e20a9e665b3118dec54838bd78488307d9175dd1ff13eeb67e05941c') - assert.equal(IN3.util.toHex(IN3.util.ecSign(pk, msg, true)) - , '0x349338b22f8c19d4c8d257595493450a88bb51cc0df48bb9b0077d1d86df3643513e0ab305ffc3d4f9a0f300d501d16556f9fb43efd1a224d6316012bb5effc71c') + assert.equal(IN3.util.toHex(IN3.util.ecSign(pk, msg, 'raw')) + , '0xf596af3336ac65b01ff4b9c632bc8af8043f8c11ae4de626c74d834412cb5a234783c14807e20a9e665b3118dec54838bd78488307d9175dd1ff13eeb67e059401') + assert.equal(IN3.util.toHex(IN3.util.ecSign(pk, msg, 'hash')) + , '0x349338b22f8c19d4c8d257595493450a88bb51cc0df48bb9b0077d1d86df3643513e0ab305ffc3d4f9a0f300d501d16556f9fb43efd1a224d6316012bb5effc701') const address = IN3.util.private2address(pk) assert.equal(address, '0x082977959d0C5A1bA627720ac753Ec2ADB5Bd7d0') @@ -123,10 +123,10 @@ describe('EthAPI-Tests', () => { assert.isTrue(await c.eth.sign(address, msg).then(_ => false, _ => true), 'must throw since we don not have a signer set') c.signer = new IN3.SimpleSigner(pk) - const sig = await c.eth.sign(address, msg) + const sig = await c.eth.sign(address, msg, 'hash') assert.equal(sig.message, '0x19457468657265756d205369676e6564204d6573736167653a0a33329fa034abf05bd334e60d92da257eb3d66dd3767bba9a1d7a7575533eb0977465') assert.equal(sig.messageHash, IN3.util.toHex(IN3.util.keccak(sig.message))) - assert.equal(sig.signature, '0x5782d5df271b9a0890f89868de73b7a206f2eb988346bc3df2c0a475d60b068a30760b12fd8cf88cd10a31dea71d9309d5b7b2f7bb49e36f69fcdbdfe480f1291c') + assert.equal(sig.signature, '0x5782d5df271b9a0890f89868de73b7a206f2eb988346bc3df2c0a475d60b068a30760b12fd8cf88cd10a31dea71d9309d5b7b2f7bb49e36f69fcdbdfe480f12901') assert.equal(sig.r, '0x5782d5df271b9a0890f89868de73b7a206f2eb988346bc3df2c0a475d60b068a') assert.equal(sig.s, '0x30760b12fd8cf88cd10a31dea71d9309d5b7b2f7bb49e36f69fcdbdfe480f129') assert.equal(sig.v, 28) diff --git a/wasm/test/testUtil.js b/wasm/test/testUtil.js index 41a317b10..bd0a00614 100644 --- a/wasm/test/testUtil.js +++ b/wasm/test/testUtil.js @@ -241,10 +241,10 @@ describe('Util-Tests', () => { const pk = '0x889dbed9450f7a4b68e0732ccb7cd016dab158e6946d16158f2736fda1143ca6' const msg = '0x9fa034abf05bd334e60d92da257eb3d66dd3767bba9a1d7a7575533eb0977465' - assert.equal(IN3.util.toHex(IN3.util.ecSign(pk, msg, false)) - , '0xf596af3336ac65b01ff4b9c632bc8af8043f8c11ae4de626c74d834412cb5a234783c14807e20a9e665b3118dec54838bd78488307d9175dd1ff13eeb67e05941c') - assert.equal(IN3.util.toHex(IN3.util.ecSign(pk, msg, true)) - , '0x349338b22f8c19d4c8d257595493450a88bb51cc0df48bb9b0077d1d86df3643513e0ab305ffc3d4f9a0f300d501d16556f9fb43efd1a224d6316012bb5effc71c') + assert.equal(IN3.util.toHex(IN3.util.ecSign(pk, msg, 'raw')) + , '0xf596af3336ac65b01ff4b9c632bc8af8043f8c11ae4de626c74d834412cb5a234783c14807e20a9e665b3118dec54838bd78488307d9175dd1ff13eeb67e059401') + assert.equal(IN3.util.toHex(IN3.util.ecSign(pk, msg, 'hash')) + , '0x349338b22f8c19d4c8d257595493450a88bb51cc0df48bb9b0077d1d86df3643513e0ab305ffc3d4f9a0f300d501d16556f9fb43efd1a224d6316012bb5effc701') const address = IN3.util.private2address(pk) assert.equal(address, '0x082977959d0C5A1bA627720ac753Ec2ADB5Bd7d0') @@ -253,10 +253,10 @@ describe('Util-Tests', () => { assert.isTrue(await c.eth.sign(address, msg).then(_ => false, _ => true), 'must throw since we don not have a signer set') c.signer = new IN3.SimpleSigner(pk) - const sig = await c.eth.sign(address, msg) + const sig = await c.eth.sign(address, msg, 'hash') assert.equal(sig.message, '0x19457468657265756d205369676e6564204d6573736167653a0a33329fa034abf05bd334e60d92da257eb3d66dd3767bba9a1d7a7575533eb0977465') assert.equal(sig.messageHash, IN3.util.toHex(IN3.util.keccak(sig.message))) - assert.equal(sig.signature, '0x5782d5df271b9a0890f89868de73b7a206f2eb988346bc3df2c0a475d60b068a30760b12fd8cf88cd10a31dea71d9309d5b7b2f7bb49e36f69fcdbdfe480f1291c') + assert.equal(sig.signature, '0x5782d5df271b9a0890f89868de73b7a206f2eb988346bc3df2c0a475d60b068a30760b12fd8cf88cd10a31dea71d9309d5b7b2f7bb49e36f69fcdbdfe480f12901') assert.equal(sig.r, '0x5782d5df271b9a0890f89868de73b7a206f2eb988346bc3df2c0a475d60b068a') assert.equal(sig.s, '0x30760b12fd8cf88cd10a31dea71d9309d5b7b2f7bb49e36f69fcdbdfe480f129') assert.equal(sig.v, 28) From 575db686bca134bc040105c5aafb2f6b093cf309 Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Thu, 9 Sep 2021 21:53:18 +0200 Subject: [PATCH 041/101] fix signData --- c/src/api/eth1/rpc_api.c | 15 +++++- c/src/core/client/request.c | 78 +++++++++++++++++----------- c/src/core/client/request_internal.h | 1 + c/src/tools/swift/swift.c | 69 +++++++++++++++++++++++- c/src/tools/swift/swift.h | 8 +++ 5 files changed, 137 insertions(+), 34 deletions(-) diff --git a/c/src/api/eth1/rpc_api.c b/c/src/api/eth1/rpc_api.c index 255efb736..25603cbd0 100644 --- a/c/src/api/eth1/rpc_api.c +++ b/c/src/api/eth1/rpc_api.c @@ -44,6 +44,7 @@ #include "../../third-party/crypto/rand.h" #include "../../third-party/crypto/secp256k1.h" #include "../../verifier/eth1/basic/eth_basic.h" +#include "../../signer/pk-signer/signer.h" #include "../../verifier/eth1/nano/rlp.h" #include "abi.h" #include "ens.h" @@ -550,6 +551,9 @@ static in3_ret_t in3_sign_data(in3_rpc_handle_ctx_t* ctx) { sc.message = data; sc.account = pk ? *pk : NULL_BYTES; sc.type = strcmp(sig_type, "hash") == 0 ? SIGN_EC_RAW : SIGN_EC_HASH; + if (strcmp(sig_type,"sign_ec_hash")==0) sc.type=SIGN_EC_HASH; + if (strcmp(sig_type,"sign_ec_raw")==0) sc.type=SIGN_EC_RAW; + if (strcmp(sig_type,"sign_ec_prefix")==0) sc.type=SIGN_EC_PREFIX; if ((sc.account.len == 20 || sc.account.len == 0) && in3_plugin_is_registered(ctx->req->client, PLGN_ACT_SIGN)) { TRY(in3_plugin_execute_first(ctx->req, PLGN_ACT_SIGN, &sc)); @@ -558,8 +562,13 @@ static in3_ret_t in3_sign_data(in3_rpc_handle_ctx_t* ctx) { sc.signature = bytes(_malloc(65), 65); if (sc.type == SIGN_EC_RAW) ecdsa_sign_digest(&secp256k1, pk->data, data.data, sc.signature.data, sc.signature.data + 64, NULL); - else if (strcmp(sig_type, "raw") == 0) + else if (strcmp(sig_type, "raw") == 0 || sc.type==SIGN_EC_HASH) ecdsa_sign(&secp256k1, HASHER_SHA3K, pk->data, data.data, data.len, sc.signature.data, sc.signature.data + 64, NULL); + else if (sc.type == SIGN_EC_PREFIX) { + bytes32_t hash; + eth_create_prefixed_msg_hash(hash, data); + ecdsa_sign_digest(&secp256k1, pk->data, hash, sc.signature.data, sc.signature.data + 64, NULL); + } else { _free(sc.signature.data); return req_set_error(ctx->req, "unsupported sigType", IN3_EINVAL); @@ -569,7 +578,9 @@ static in3_ret_t in3_sign_data(in3_rpc_handle_ctx_t* ctx) { return req_set_error(ctx->req, "Invalid private key! Must be either an address(20 byte) or an raw private key (32 byte)", IN3_EINVAL); bytes_t sig_bytes = sc.signature; - if (sc.signature.len == 65 && sc.signature.data[64] < 2) + + // we only correct the v value, if the sig_type is a simple type. if it is a sign_ec- type, we don't + if (strncmp(sig_type, "sign_ec_",8) && sc.signature.len == 65 && sc.signature.data[64] < 2) sc.signature.data[64] += 27; sb_t* sb = in3_rpc_handle_start(ctx); diff --git a/c/src/core/client/request.c b/c/src/core/client/request.c index ed272125f..8e3ae9827 100644 --- a/c/src/core/client/request.c +++ b/c/src/core/client/request.c @@ -425,36 +425,28 @@ in3_ret_t req_send_sub_request(in3_req_t* parent, char* method, char* params, ch return ret; } -in3_ret_t req_require_signature(in3_req_t* ctx, d_signature_type_t type, d_payload_type_t pl_type, bytes_t* signature, bytes_t raw_data, bytes_t from, d_token_t* meta) { - bytes_t cache_key = bytes(alloca(raw_data.len + from.len), raw_data.len + from.len); - memcpy(cache_key.data, raw_data.data, raw_data.len); - if (from.data) memcpy(cache_key.data + raw_data.len, from.data, from.len); +in3_ret_t req_send_sign_request(in3_req_t* ctx, d_signature_type_t type, d_payload_type_t pl_type, bytes_t* signature, bytes_t raw_data, bytes_t from, d_token_t* meta, bytes_t cache_key) { + bytes_t* cached_sig = in3_cache_get_entry(ctx->cache, &cache_key); if (cached_sig) { *signature = *cached_sig; return IN3_OK; } - in3_log_debug("requesting signature type=%d from account %x\n", type, from.len > 2 ? bytes_to_int(from.data, 4) : 0); - - // first try internal plugins for signing, before we create an context. - if (in3_plugin_is_registered(ctx->client, PLGN_ACT_SIGN)) { - in3_sign_ctx_t sc = {.account = from, .req = ctx, .message = raw_data, .signature = NULL_BYTES, .type = type, .payload_type = pl_type, .meta = meta}; - in3_ret_t r = in3_plugin_execute_first_or_none(ctx, PLGN_ACT_SIGN, &sc); - if (r == IN3_OK && sc.signature.data) { - in3_cache_add_entry(&ctx->cache, cloned_bytes(cache_key), sc.signature); - *signature = sc.signature; - return IN3_OK; - } - else if (r != IN3_EIGNORE && r != IN3_OK) - return r; - } - in3_log_debug("nobody picked up the signature, sending req now \n"); - // get the signature from required const char* method = type == SIGN_EC_HASH ? "sign_ec_hash" : (type == SIGN_EC_PREFIX ? "sign_ec_prefix" : "sign_ec_raw"); - in3_req_t* c = req_find_required(ctx, method, NULL); - if (c) + sb_t params = {0}; + sb_add_bytes(¶ms, "[", &raw_data, 1, false); + sb_add_chars(¶ms, ","); + sb_add_bytes(¶ms, NULL, &from, 1, false); + sb_add_chars(¶ms, ","); + sb_add_int(¶ms, (int64_t) pl_type); + sb_add_json(¶ms, ",", meta); + sb_add_chars(¶ms, "]"); + + in3_req_t* c = req_find_required(ctx, method, params.data); + if (c) { + _free(params.data); switch (in3_req_state(c)) { case REQ_ERROR: return req_set_error(ctx, c->error ? c->error : "Could not handle signing", IN3_ERPC); @@ -462,7 +454,7 @@ in3_ret_t req_require_signature(in3_req_t* ctx, d_signature_type_t type, d_paylo case REQ_WAITING_TO_SEND: return IN3_WAITING; case REQ_SUCCESS: { - if (c->raw_response && c->raw_response->state == IN3_OK && c->raw_response->data.len == 65) { + if (c->raw_response && c->raw_response->state == IN3_OK && c->raw_response->data.len > 64) { *signature = cloned_bytes(bytes((uint8_t*) c->raw_response->data.data, c->raw_response->data.len)); in3_cache_add_entry(&ctx->cache, cloned_bytes(cache_key), *signature); req_remove_required(ctx, c, false); @@ -476,17 +468,15 @@ in3_ret_t req_require_signature(in3_req_t* ctx, d_signature_type_t type, d_paylo return req_set_error(ctx, "invalid state", IN3_EINVAL); } } + } else { sb_t req = {0}; sb_add_chars(&req, "{\"method\":\""); sb_add_chars(&req, method); - sb_add_bytes(&req, "\",\"params\":[", &raw_data, 1, false); - sb_add_chars(&req, ","); - sb_add_bytes(&req, NULL, &from, 1, false); - sb_add_chars(&req, ","); - sb_add_int(&req, (int64_t) pl_type); - sb_add_json(&req, ",", meta); - sb_add_chars(&req, "]}"); + sb_add_chars(&req, "\",\"params\":"); + sb_add_chars(&req, params.data); + sb_add_chars(&req, "}"); + _free(params.data); c = req_new(ctx->client, req.data); if (!c) return IN3_ECONFIG; c->type = RT_SIGN; @@ -494,6 +484,34 @@ in3_ret_t req_require_signature(in3_req_t* ctx, d_signature_type_t type, d_paylo } } +in3_ret_t req_require_signature(in3_req_t* ctx, d_signature_type_t type, d_payload_type_t pl_type, bytes_t* signature, bytes_t raw_data, bytes_t from, d_token_t* meta) { + bytes_t cache_key = bytes(alloca(raw_data.len + from.len), raw_data.len + from.len); + memcpy(cache_key.data, raw_data.data, raw_data.len); + if (from.data) memcpy(cache_key.data + raw_data.len, from.data, from.len); + bytes_t* cached_sig = in3_cache_get_entry(ctx->cache, &cache_key); + if (cached_sig) { + *signature = *cached_sig; + return IN3_OK; + } + + in3_log_debug("requesting signature type=%d from account %x\n", type, from.len > 2 ? bytes_to_int(from.data, 4) : 0); + + // first try internal plugins for signing, before we create an context. + if (in3_plugin_is_registered(ctx->client, PLGN_ACT_SIGN)) { + in3_sign_ctx_t sc = {.account = from, .req = ctx, .message = raw_data, .signature = NULL_BYTES, .type = type, .payload_type = pl_type, .meta = meta}; + in3_ret_t r = in3_plugin_execute_first_or_none(ctx, PLGN_ACT_SIGN, &sc); + if (r == IN3_OK && sc.signature.data) { + in3_cache_add_entry(&ctx->cache, cloned_bytes(cache_key), sc.signature); + *signature = sc.signature; + return IN3_OK; + } + else if (r != IN3_EIGNORE && r != IN3_OK) + return r; + } + in3_log_debug("nobody picked up the signature, sending req now \n"); + return req_send_sign_request(ctx, type, pl_type, signature, raw_data, from, meta, cache_key); +} + in3_ret_t vc_set_error(in3_vctx_t* vc, char* msg) { #ifdef LOGGING (void) req_set_error(vc->req, msg, IN3_EUNKNOWN); diff --git a/c/src/core/client/request_internal.h b/c/src/core/client/request_internal.h index 6eb926d04..bf243c1ad 100644 --- a/c/src/core/client/request_internal.h +++ b/c/src/core/client/request_internal.h @@ -117,5 +117,6 @@ NONULL in3_ret_t in3_retry_same_node(in3_req_t* req); NONULL void in3_req_free_nodes(node_match_t* c); int req_nodes_len(node_match_t* root); NONULL bool req_is_method(const in3_req_t* req, const char* method); +in3_ret_t req_send_sign_request(in3_req_t* ctx, d_signature_type_t type, d_payload_type_t pl_type, bytes_t* signature, bytes_t raw_data, bytes_t from, d_token_t* meta, bytes_t cache_key); #endif // REQ_INTERNAL_H \ No newline at end of file diff --git a/c/src/tools/swift/swift.c b/c/src/tools/swift/swift.c index 9ec093f0d..4694b0ece 100644 --- a/c/src/tools/swift/swift.c +++ b/c/src/tools/swift/swift.c @@ -1,5 +1,13 @@ #include "swift.h" +#include "../../core/client/client.h" +#include "../../core/client/keys.h" +#include "../../core/client/plugin.h" +#include "../../core/client/request.h" +#include "../../core/client/request_internal.h" +#include "../../core/util/debug.h" +#include "../../core/util/log.h" +#include "../../third-party/crypto/sha3.h" static in3_ret_t handle(void* plugin_data, in3_plugin_act_t action, void* plugin_ctx) { swift_cb_t* conf = plugin_data; @@ -15,6 +23,35 @@ static in3_ret_t handle(void* plugin_data, in3_plugin_act_t action, void* plugin in3_cache_ctx_t* _Nonnull ctx = plugin_ctx; return conf->cache_set(ctx); } + case PLGN_ACT_SIGN_ACCOUNT: { + in3_sign_account_ctx_t* _Nonnull ctx = plugin_ctx; + char* accounts = conf->sign_accounts(ctx); + if (accounts) { + size_t l = strlen(accounts); + if (l % 40 == 0) { + ctx->accounts_len = l / 40; + ctx->accounts = _malloc(l / 2); + hex_to_bytes(accounts, l, ctx->accounts, l / 2); + } + _free(accounts); + } + return IN3_OK; + } + case PLGN_ACT_SIGN: { + in3_sign_ctx_t* _Nonnull ctx = plugin_ctx; + bytes_t signature = NULL_BYTES; + bytes32_t msghash; + + struct SHA3_CTX kctx; + sha3_256_Init(&kctx); + sha3_Update(&kctx, ctx->message.data, ctx->message.len); + if (ctx->account.data) sha3_Update(&kctx, ctx->account.data, ctx->account.len); + keccak_Final(&kctx, msghash); + + TRY(req_send_sign_request(ctx->req, ctx->type, ctx->payload_type, &signature, ctx->message, ctx->account, ctx->meta, bytes(msghash, 32))) + ctx->signature = bytes_dup(signature); + return IN3_OK; + } case PLGN_ACT_CACHE_CLEAR: return conf->cache_clear(); @@ -27,5 +64,33 @@ static in3_ret_t handle(void* plugin_data, in3_plugin_act_t action, void* plugin in3_ret_t in3_register_swift(in3_t* c, swift_cb_t* cbs) { swift_cb_t* ptr = _malloc(sizeof(swift_cb_t)); memcpy(ptr, cbs, sizeof(swift_cb_t)); - return in3_plugin_register(c, PLGN_ACT_CACHE_GET | PLGN_ACT_CACHE_SET | PLGN_ACT_CACHE_CLEAR | PLGN_ACT_TERM, handle, ptr, true); -} \ No newline at end of file + return in3_plugin_register(c, PLGN_ACT_CACHE_GET | PLGN_ACT_CACHE_SET | PLGN_ACT_CACHE_CLEAR | PLGN_ACT_TERM | PLGN_ACT_SIGN_ACCOUNT | PLGN_ACT_SIGN, handle, ptr, true); +} + +char* sign_get_method(in3_req_t* r) { + return d_get_string(r->requests[0],K_METHOD); +} + +bytes_t sign_get_message(in3_req_t* r) { + d_token_t* params =d_get(r->requests[0],K_PARAMS); + return d_to_bytes(d_get_at(params,0)); +} +uint8_t* sign_get_from(in3_req_t* r) { + d_token_t* params =d_get(r->requests[0],K_PARAMS); + return d_to_bytes(d_get_at(params,1)).data; +} + + +int sign_get_payload_type(in3_req_t* r) { + d_token_t* params =d_get(r->requests[0],K_PARAMS); + return d_get_int_at(params,2); +} + + +char* sign_get_metadata(in3_req_t* r) { + d_token_t* params =d_get(r->requests[0],K_PARAMS); + d_token_t* meta = d_get_at(params,3); + return meta ? d_create_json(r->request_context, meta) : NULL; +} + + diff --git a/c/src/tools/swift/swift.h b/c/src/tools/swift/swift.h index 0243b1e66..b44ff7c3f 100644 --- a/c/src/tools/swift/swift.h +++ b/c/src/tools/swift/swift.h @@ -31,6 +31,7 @@ * You should have received a copy of the GNU Affero General Public License along * with this program. If not, see . *******************************************************************************/ +// @PUBLIC_HEADER #ifndef IN3_SWIFT_H #define IN3_SWIFT_H #ifdef __clang__ @@ -44,8 +45,15 @@ typedef struct in3_swift_cb { in3_ret_t (*_NONULL cache_get)(in3_cache_ctx_t* _Nonnull ctx); in3_ret_t (*_NONULL cache_set)(in3_cache_ctx_t* _Nonnull ctx); in3_ret_t (*_NONULL cache_clear)(); + char* (*_NONULL sign_accounts)(in3_sign_account_ctx_t* _Nonnull ctx); } swift_cb_t; in3_ret_t in3_register_swift(in3_t* _NONULL c, swift_cb_t* _NONULL cbs); + +char* sign_get_method(in3_req_t* r); +bytes_t sign_get_message(in3_req_t* r); +uint8_t* sign_get_from(in3_req_t* r); +int sign_get_payload_type(in3_req_t* r); +char* sign_get_metadata(in3_req_t* r); #endif // IN3_SWIFT_H From cc4c1190176e92d9fb90817888c4bde1ae4b88f9 Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Thu, 9 Sep 2021 21:56:08 +0200 Subject: [PATCH 042/101] fix format --- c/src/api/eth1/rpc_api.c | 20 ++++++++++---------- c/src/tools/swift/swift.h | 9 ++++----- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/c/src/api/eth1/rpc_api.c b/c/src/api/eth1/rpc_api.c index 25603cbd0..737d2ce4f 100644 --- a/c/src/api/eth1/rpc_api.c +++ b/c/src/api/eth1/rpc_api.c @@ -39,12 +39,12 @@ #include "../../core/util/debug.h" #include "../../core/util/log.h" #include "../../core/util/mem.h" +#include "../../signer/pk-signer/signer.h" #include "../../third-party/crypto/bignum.h" #include "../../third-party/crypto/ecdsa.h" #include "../../third-party/crypto/rand.h" #include "../../third-party/crypto/secp256k1.h" #include "../../verifier/eth1/basic/eth_basic.h" -#include "../../signer/pk-signer/signer.h" #include "../../verifier/eth1/nano/rlp.h" #include "abi.h" #include "ens.h" @@ -551,9 +551,9 @@ static in3_ret_t in3_sign_data(in3_rpc_handle_ctx_t* ctx) { sc.message = data; sc.account = pk ? *pk : NULL_BYTES; sc.type = strcmp(sig_type, "hash") == 0 ? SIGN_EC_RAW : SIGN_EC_HASH; - if (strcmp(sig_type,"sign_ec_hash")==0) sc.type=SIGN_EC_HASH; - if (strcmp(sig_type,"sign_ec_raw")==0) sc.type=SIGN_EC_RAW; - if (strcmp(sig_type,"sign_ec_prefix")==0) sc.type=SIGN_EC_PREFIX; + if (strcmp(sig_type, "sign_ec_hash") == 0) sc.type = SIGN_EC_HASH; + if (strcmp(sig_type, "sign_ec_raw") == 0) sc.type = SIGN_EC_RAW; + if (strcmp(sig_type, "sign_ec_prefix") == 0) sc.type = SIGN_EC_PREFIX; if ((sc.account.len == 20 || sc.account.len == 0) && in3_plugin_is_registered(ctx->req->client, PLGN_ACT_SIGN)) { TRY(in3_plugin_execute_first(ctx->req, PLGN_ACT_SIGN, &sc)); @@ -562,12 +562,12 @@ static in3_ret_t in3_sign_data(in3_rpc_handle_ctx_t* ctx) { sc.signature = bytes(_malloc(65), 65); if (sc.type == SIGN_EC_RAW) ecdsa_sign_digest(&secp256k1, pk->data, data.data, sc.signature.data, sc.signature.data + 64, NULL); - else if (strcmp(sig_type, "raw") == 0 || sc.type==SIGN_EC_HASH) + else if (strcmp(sig_type, "raw") == 0 || sc.type == SIGN_EC_HASH) ecdsa_sign(&secp256k1, HASHER_SHA3K, pk->data, data.data, data.len, sc.signature.data, sc.signature.data + 64, NULL); else if (sc.type == SIGN_EC_PREFIX) { - bytes32_t hash; - eth_create_prefixed_msg_hash(hash, data); - ecdsa_sign_digest(&secp256k1, pk->data, hash, sc.signature.data, sc.signature.data + 64, NULL); + bytes32_t hash; + eth_create_prefixed_msg_hash(hash, data); + ecdsa_sign_digest(&secp256k1, pk->data, hash, sc.signature.data, sc.signature.data + 64, NULL); } else { _free(sc.signature.data); @@ -578,9 +578,9 @@ static in3_ret_t in3_sign_data(in3_rpc_handle_ctx_t* ctx) { return req_set_error(ctx->req, "Invalid private key! Must be either an address(20 byte) or an raw private key (32 byte)", IN3_EINVAL); bytes_t sig_bytes = sc.signature; - + // we only correct the v value, if the sig_type is a simple type. if it is a sign_ec- type, we don't - if (strncmp(sig_type, "sign_ec_",8) && sc.signature.len == 65 && sc.signature.data[64] < 2) + if (strncmp(sig_type, "sign_ec_", 8) && sc.signature.len == 65 && sc.signature.data[64] < 2) sc.signature.data[64] += 27; sb_t* sb = in3_rpc_handle_start(ctx); diff --git a/c/src/tools/swift/swift.h b/c/src/tools/swift/swift.h index b44ff7c3f..4f41837bb 100644 --- a/c/src/tools/swift/swift.h +++ b/c/src/tools/swift/swift.h @@ -50,10 +50,9 @@ typedef struct in3_swift_cb { in3_ret_t in3_register_swift(in3_t* _NONULL c, swift_cb_t* _NONULL cbs); - -char* sign_get_method(in3_req_t* r); -bytes_t sign_get_message(in3_req_t* r); +char* sign_get_method(in3_req_t* r); +bytes_t sign_get_message(in3_req_t* r); uint8_t* sign_get_from(in3_req_t* r); -int sign_get_payload_type(in3_req_t* r); -char* sign_get_metadata(in3_req_t* r); +int sign_get_payload_type(in3_req_t* r); +char* sign_get_metadata(in3_req_t* r); #endif // IN3_SWIFT_H From d3f936e12f3d82b785bef369179fa24c114f73ad Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Thu, 9 Sep 2021 21:56:17 +0200 Subject: [PATCH 043/101] format --- c/src/tools/swift/swift.c | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/c/src/tools/swift/swift.c b/c/src/tools/swift/swift.c index 4694b0ece..04ec17bfa 100644 --- a/c/src/tools/swift/swift.c +++ b/c/src/tools/swift/swift.c @@ -68,29 +68,25 @@ in3_ret_t in3_register_swift(in3_t* c, swift_cb_t* cbs) { } char* sign_get_method(in3_req_t* r) { - return d_get_string(r->requests[0],K_METHOD); + return d_get_string(r->requests[0], K_METHOD); } - + bytes_t sign_get_message(in3_req_t* r) { - d_token_t* params =d_get(r->requests[0],K_PARAMS); - return d_to_bytes(d_get_at(params,0)); + d_token_t* params = d_get(r->requests[0], K_PARAMS); + return d_to_bytes(d_get_at(params, 0)); } uint8_t* sign_get_from(in3_req_t* r) { - d_token_t* params =d_get(r->requests[0],K_PARAMS); - return d_to_bytes(d_get_at(params,1)).data; + d_token_t* params = d_get(r->requests[0], K_PARAMS); + return d_to_bytes(d_get_at(params, 1)).data; } - int sign_get_payload_type(in3_req_t* r) { - d_token_t* params =d_get(r->requests[0],K_PARAMS); - return d_get_int_at(params,2); + d_token_t* params = d_get(r->requests[0], K_PARAMS); + return d_get_int_at(params, 2); } - char* sign_get_metadata(in3_req_t* r) { - d_token_t* params =d_get(r->requests[0],K_PARAMS); - d_token_t* meta = d_get_at(params,3); + d_token_t* params = d_get(r->requests[0], K_PARAMS); + d_token_t* meta = d_get_at(params, 3); return meta ? d_create_json(r->request_context, meta) : NULL; } - - From 4d033d1623eb0da13dd118157ce3281020661450 Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Thu, 9 Sep 2021 22:30:12 +0200 Subject: [PATCH 044/101] fix error when calling the signer without matching accounts --- c/src/tools/swift/swift.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/c/src/tools/swift/swift.c b/c/src/tools/swift/swift.c index 04ec17bfa..fa1c7cc51 100644 --- a/c/src/tools/swift/swift.c +++ b/c/src/tools/swift/swift.c @@ -34,12 +34,40 @@ static in3_ret_t handle(void* plugin_data, in3_plugin_act_t action, void* plugin hex_to_bytes(accounts, l, ctx->accounts, l / 2); } _free(accounts); + return l > 2 ? IN3_OK : IN3_EIGNORE; } - return IN3_OK; + return IN3_EIGNORE; } case PLGN_ACT_SIGN: { in3_sign_ctx_t* _Nonnull ctx = plugin_ctx; - bytes_t signature = NULL_BYTES; + + in3_sign_account_ctx_t sctx = {0}; + sctx.req = ctx->req; + char* accounts = conf->sign_accounts(&sctx); + if (!accounts) return IN3_EIGNORE; + int l = strlen(accounts); + if (l < 3) { + _free(accounts); + return IN3_EIGNORE; + } + + if (ctx->account.len == 20) { + char adr[41]; + bytes_to_hex_string(adr, "", ctx->account, ""); + bool found = false; + for (int i = 2; i < l; i += 40) { + if (strncmp(adr, accounts + i, 40) == 0) { + found = true; + break; + } + } + _free(accounts); + if (!found) return IN3_EIGNORE; + } + else + _free(accounts); + + bytes_t signature = NULL_BYTES; bytes32_t msghash; struct SHA3_CTX kctx; From f850bdd732f2587d414d0d50c8f98d4f7ca7a169 Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Fri, 10 Sep 2021 06:57:45 +0200 Subject: [PATCH 045/101] fix dependency --- c/src/api/eth1/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/c/src/api/eth1/CMakeLists.txt b/c/src/api/eth1/CMakeLists.txt index 12773519a..64626780f 100644 --- a/c/src/api/eth1/CMakeLists.txt +++ b/c/src/api/eth1/CMakeLists.txt @@ -59,6 +59,7 @@ add_static_library( DEPENDS eth_nano api_utils + pk_signer ${LIBS} ) From 96dede2d1b52344c22304c4a26a50f9e9f6ce180 Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Fri, 10 Sep 2021 13:02:21 +0200 Subject: [PATCH 046/101] allow to build without cryptolib --- c/options.cmake | 5 +++++ c/src/api/CMakeLists.txt | 6 ++++-- c/src/core/CMakeLists.txt | 7 ++++--- c/src/core/client/execute.c | 14 ++++++++++++++ c/src/core/util/utils.c | 6 ++++++ c/src/init/CMakeLists.txt | 1 + c/src/third-party/CMakeLists.txt | 4 +++- scripts/build.sh | 5 ++++- wasm/src/wasm.c | 22 ++++++++++++++++++---- 9 files changed, 59 insertions(+), 11 deletions(-) diff --git a/c/options.cmake b/c/options.cmake index 2406e1628..51213b40b 100644 --- a/c/options.cmake +++ b/c/options.cmake @@ -50,6 +50,7 @@ OPTION(PLGN_CLIENT_DATA "Enable client-data plugin" OFF) OPTION(THREADSAFE "uses mutex to protect shared nodelist access" ON) OPTION(SWIFT "swift API for swift bindings" OFF) OPTION(CORE_API "include basic core-utils" ON) +OPTION(CRYPTO_LIB "include crypto-lib" ON) OPTION(RPC_ONLY "specifies a coma-seperqted list of rpc-methods which should be supported. all other rpc-methods will be removed reducing the size of executable a lot." OFF) @@ -75,6 +76,10 @@ IF (BTC_PRE_BPI34) ADD_DEFINITIONS(-DBTC_PRE_BPI34) ENDIF (BTC_PRE_BPI34) +IF (CRYPTO_LIB) + ADD_DEFINITIONS(-DCRYPTO_LIB) +ENDIF (CRYPTO_LIB) + IF (POA) ADD_DEFINITIONS(-DPOA) ENDIF (POA) diff --git a/c/src/api/CMakeLists.txt b/c/src/api/CMakeLists.txt index cd8eb20d6..1a98b983c 100644 --- a/c/src/api/CMakeLists.txt +++ b/c/src/api/CMakeLists.txt @@ -32,10 +32,12 @@ # with this program. If not, see . ############################################################################### -add_subdirectory(utils) -add_subdirectory(core) IF (IN3API) + add_subdirectory(utils) + add_subdirectory(core) + + add_subdirectory(eth1) if (NOT WASM) diff --git a/c/src/core/CMakeLists.txt b/c/src/core/CMakeLists.txt index e557ab6d9..da5ac2f2a 100644 --- a/c/src/core/CMakeLists.txt +++ b/c/src/core/CMakeLists.txt @@ -57,7 +57,8 @@ add_static_library( util/mem.c util/stringbuilder.c util/bitset.c - - DEPENDS - crypto ) + +if(CRYPTO_LIB) + target_link_libraries(core crypto) +endif() \ No newline at end of file diff --git a/c/src/core/client/execute.c b/c/src/core/client/execute.c index 67658d5bf..5bf77535c 100644 --- a/c/src/core/client/execute.c +++ b/c/src/core/client/execute.c @@ -116,11 +116,17 @@ static void free_urls(char** urls, int len) { static int add_bytes_to_hash(struct SHA3_CTX* msg_hash, void* data, int len) { assert(data); +#ifdef CRYPTO_LIB if (msg_hash) sha3_Update(msg_hash, data, len); +#else + UNUSED_VAR(msg_hash); + UNUSED_VAR(data); +#endif return len; } NONULL static void add_token_to_hash(struct SHA3_CTX* msg_hash, d_token_t* t) { +#ifdef CRYPTO_LIB switch (d_type(t)) { case T_ARRAY: case T_OBJECT: @@ -135,6 +141,10 @@ NONULL static void add_token_to_hash(struct SHA3_CTX* msg_hash, d_token_t* t) { sha3_Update(msg_hash, b.data, b.len); } } +#else + UNUSED_VAR(msg_hash); + UNUSED_VAR(t); +#endif } NONULL static in3_ret_t ctx_create_payload(in3_req_t* c, sb_t* sb, bool no_in3) { @@ -150,7 +160,9 @@ NONULL static in3_ret_t ctx_create_payload(in3_req_t* c, sb_t* sb, bool no_in3) for (uint16_t i = 0; i < c->len; i++) { d_token_t * request_token = c->requests[i], *t; in3_proof_t proof = no_in3 ? PROOF_NONE : in3_req_get_proof(c, i); +#ifdef CRYPTO_LIB if (msg_hash) sha3_256_Init(msg_hash); +#endif if (i > 0) sb_add_char(sb, ','); sb_add_char(sb, '{'); @@ -187,11 +199,13 @@ NONULL static in3_ret_t ctx_create_payload(in3_req_t* c, sb_t* sb, bool no_in3) TRY(in3_plugin_execute_first_or_none(c, PLGN_ACT_ADD_PAYLOAD, &pctx)) if (msg_hash) { +#ifdef CRYPTO_LIB in3_pay_sign_req_ctx_t sctx = {.req = c, .request = request_token, .signature = {0}}; bytes_t sig_bytes = bytes(sctx.signature, 65); keccak_Final(msg_hash, sctx.request_hash); TRY(in3_plugin_execute_first(c, PLGN_ACT_PAY_SIGN_REQ, &sctx)) sb_add_bytes(sb, ",\"sig\":", &sig_bytes, 1, false); +#endif } if (rc->finality) sb_add_range(sb, temp, 0, sprintf(temp, ",\"finality\":%i", rc->finality)); diff --git a/c/src/core/util/utils.c b/c/src/core/util/utils.c index e19168bdb..1d3374436 100644 --- a/c/src/core/util/utils.c +++ b/c/src/core/util/utils.c @@ -207,11 +207,17 @@ char* bytes_to_hex_string(char* out, const char* prefix, const bytes_t b, const /** writes 32 bytes to the pointer. */ int keccak(bytes_t data, void* dst) { +#ifdef CRYPTO_LIB struct SHA3_CTX ctx; sha3_256_Init(&ctx); if (data.len) sha3_Update(&ctx, data.data, data.len); keccak_Final(&ctx, dst); return 0; +#else + UNUSED_VAR(data); + UNUSED_VAR(dst); + return -1; +#endif } uint64_t bytes_to_long(const uint8_t* data, int len) { diff --git a/c/src/init/CMakeLists.txt b/c/src/init/CMakeLists.txt index f360ef427..ce6b96f73 100644 --- a/c/src/init/CMakeLists.txt +++ b/c/src/init/CMakeLists.txt @@ -42,6 +42,7 @@ add_static_library( in3_init.c DEPENDS + core ${IN3_VERIFIER} ${IN3_API} ${IN3_TRANSPORT} diff --git a/c/src/third-party/CMakeLists.txt b/c/src/third-party/CMakeLists.txt index 4a5e5a58a..975340159 100644 --- a/c/src/third-party/CMakeLists.txt +++ b/c/src/third-party/CMakeLists.txt @@ -32,7 +32,9 @@ # with this program. If not, see . ############################################################################### -add_subdirectory( crypto ) +if(CRYPTO_LIB) + add_subdirectory( crypto ) +endif() if(USE_SCRYPT) add_subdirectory( libscrypt ) endif() diff --git a/scripts/build.sh b/scripts/build.sh index 3cc7b7685..400fee2d8 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -30,7 +30,7 @@ if [ "$CONTAINER" = "bindings-debug" ]; then OPTS="-DUSE_CURL=false" fi if [ -z "$BUILDTYPE" ]; then - BUILDTYPE=DEBUGG + BUILDTYPE=DEBUG #TEST=true fi if [ "$BUILDTYPE" = "release" ]; then @@ -45,6 +45,9 @@ fi MIN_OPTS="-DUSE_SCRYPT=false -DETH_BASIC=true -DETH_FULL=false -DTHREADSAFE=false -DMULTISIG=false -DLOGGING=false -DCMAKE_EXPORT_COMPILE_COMMANDS=true -DTAG_VERSION=$VERSION -DZKCRYPTO_LIB=true -DTEST=$TEST -DBUILD_DOC=$TEST -DJAVA=$TEST -DZKSYNC=false -DIN3_SERVER=false -DBTC=false -DIPFS=false -DCMAKE_BUILD_TYPE=$BUILDTYPE $OPTS " FULL_OPTS="-DUSE_SCRYPT=true -DETH_BASIC=true -DETH_FULL=true -DTHREADSAFE=true -DMULTISIG=true -DLOGGING=true -DCMAKE_EXPORT_COMPILE_COMMANDS=true -DTAG_VERSION=$VERSION -DZKCRYPTO_LIB=true -DTEST=$TEST -DBUILD_DOC=$TEST -DJAVA=$TEST -DZKSYNC=true -DIN3_SERVER=true -DBTC=true -DIPFS=true -DCMAKE_BUILD_TYPE=$BUILDTYPE $OPTS " +TINY_OPTS=" -DPK_SIGNER=false -DCMAKE_EXPORT_COMPILE_COMMANDS=true -DWASM=true -DASMJS=false -DWASM_EMMALLOC=true -DBTC=false -DNODESELECT_DEF_WL=false -DNODESELECT_DEF=false -DIN3API=false -DIPFS=false -DZKSYNC=false -DMULTISIG=false -DETH_FULL=false -DETH_BASIC=false -DETH_NANO=false -DLOGGING=true -DUSE_SCRYPT=false -DCORE_API=false -DWASM_EMBED=false -DCRYPTO_LIB=false -DCMAKE_BUILD_TYPE=MINSIZEREL" + + OPTS=$FULL_OPTS diff --git a/wasm/src/wasm.c b/wasm/src/wasm.c index 27f67f72d..89c4b4393 100644 --- a/wasm/src/wasm.c +++ b/wasm/src/wasm.c @@ -37,8 +37,10 @@ #include "../../c/src/core/client/version.h" #include "../../c/src/core/util/mem.h" #include "../../c/src/init/in3_init.h" +#ifdef NODESELECT_DEF #include "../../c/src/nodeselect/full/cache.h" #include "../../c/src/nodeselect/full/nodelist.h" +#endif #include "../../c/src/third-party/crypto/ecdsa.h" #include "../../c/src/third-party/crypto/secp256k1.h" #include "../../c/src/third-party/crypto/sha2.h" @@ -397,6 +399,7 @@ uint8_t* EMSCRIPTEN_KEEPALIVE hash_keccak(uint8_t* data, int len) { uint8_t* EMSCRIPTEN_KEEPALIVE hash_sha256(uint8_t* data, int len) { uint8_t* result = malloc(32); +#ifdef CRYPTO_LIB if (result) { SHA256_CTX c; sha256_Init(&c); @@ -405,6 +408,9 @@ uint8_t* EMSCRIPTEN_KEEPALIVE hash_sha256(uint8_t* data, int len) { } else in3_set_error("malloc failed"); +#else + in3_set_error("no cryptolib installer"); +#endif return result; } @@ -504,26 +510,31 @@ char* EMSCRIPTEN_KEEPALIVE wasm_to_hex(char* val) { /** private key to address */ uint8_t* EMSCRIPTEN_KEEPALIVE private_to_address(bytes32_t prv_key) { uint8_t* dst = malloc(20); - uint8_t public_key[65], sdata[32]; +#ifdef CRYPTO_LIB + uint8_t public_key[65], sdata[32]; ecdsa_get_public_key65(&secp256k1, prv_key, public_key); keccak(bytes(public_key + 1, 64), sdata); memcpy(dst, sdata + 12, 20); +#endif return dst; } /** private key to address */ uint8_t* EMSCRIPTEN_KEEPALIVE private_to_public(bytes32_t prv_key) { uint8_t* dst = malloc(64); - uint8_t public_key[65], sdata[32]; +#ifdef CRYPTO_LIB + uint8_t public_key[65], sdata[32]; ecdsa_get_public_key65(&secp256k1, prv_key, public_key); memcpy(dst, public_key + 1, 64); +#endif return dst; } /** signs the given data */ uint8_t* EMSCRIPTEN_KEEPALIVE ec_sign(bytes32_t pk, d_signature_type_t type, uint8_t* data, int len, bool adjust_v) { - uint8_t* dst = malloc(65); - int error = -1; + uint8_t* dst = malloc(65); +#ifdef CRYPTO_LIB + int error = -1; switch (type) { case SIGN_EC_PREFIX: { bytes32_t hash; @@ -553,5 +564,8 @@ uint8_t* EMSCRIPTEN_KEEPALIVE ec_sign(bytes32_t pk, d_signature_type_t type, uin return NULL; } if (adjust_v) dst[64] += 27; +#else + in3_set_error("no cryptolib installer"); +#endif return dst; } From 4abe03fe364e8f800f4df637745317aaff2ed94d Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Fri, 10 Sep 2021 13:31:30 +0200 Subject: [PATCH 047/101] fix warnings --- c/options.cmake | 2 +- c/src/core/client/client_init.c | 1 + c/src/core/client/execute.c | 1 + c/src/core/client/request.c | 2 ++ 4 files changed, 5 insertions(+), 1 deletion(-) diff --git a/c/options.cmake b/c/options.cmake index 51213b40b..f7178d4ff 100644 --- a/c/options.cmake +++ b/c/options.cmake @@ -89,7 +89,7 @@ IF (PK_SIGNER) set(IN3_API ${IN3_API} pk_signer) ENDIF (PK_SIGNER) -IF (CORE_API) +IF (CORE_API AND IN3API) set(IN3_API ${IN3_API} core_api) ENDIF (CORE_API) diff --git a/c/src/core/client/client_init.c b/c/src/core/client/client_init.c index ced7b1ef4..3f3171882 100644 --- a/c/src/core/client/client_init.c +++ b/c/src/core/client/client_init.c @@ -504,6 +504,7 @@ in3_ret_t in3_plugin_execute_first(in3_req_t* ctx, in3_plugin_act_t action, void sprintf(msg, "no plugin found that handled the %s action", name); #else char* msg = "E"; + UNUSED_VAR(msg); // this makes sure we don't get a warning when building with _DLOGGING=false #endif return req_set_error(ctx, msg, IN3_EPLGN_NONE); } diff --git a/c/src/core/client/execute.c b/c/src/core/client/execute.c index 5bf77535c..7e5f49607 100644 --- a/c/src/core/client/execute.c +++ b/c/src/core/client/execute.c @@ -776,6 +776,7 @@ void in3_handle_rpc(in3_req_t* ctx, ctx_req_transports_t* transports) { for (unsigned int i = 0; i < request->urls_len; i++, node = node ? node->next : NULL) { if (request->req->raw_response[i].state != IN3_WAITING) { char* data = request->req->raw_response[i].data.data; + UNUSED_VAR(data); // this makes sure we don't get a warning when building with _DLOGGING=false #ifdef DEBUG data = format_json(data); #endif diff --git a/c/src/core/client/request.c b/c/src/core/client/request.c index 8e3ae9827..ee0c38f2d 100644 --- a/c/src/core/client/request.c +++ b/c/src/core/client/request.c @@ -384,6 +384,7 @@ in3_ret_t req_send_sub_request(in3_req_t* parent, char* method, char* params, ch *result = strcmp(method, "in3_http") == 0 ? ctx->responses[0] : d_get(ctx->responses[0], K_RESULT); if (!*result) { char* s = d_get_string(d_get(ctx->responses[0], K_ERROR), K_MESSAGE); + UNUSED_VAR(s); // this makes sure we don't get a warning when building with _DLOGGING=false return req_set_error(parent, s ? s : "error executing provider call", IN3_ERPC); } return IN3_OK; @@ -419,6 +420,7 @@ in3_ret_t req_send_sub_request(in3_req_t* parent, char* method, char* params, ch *result = d_get(ctx->responses[0], K_RESULT); if (!*result) { char* s = d_get_string(d_get(ctx->responses[0], K_ERROR), K_MESSAGE); + UNUSED_VAR(s); // this makes sure we don't get a warning when building with _DLOGGING=false return req_set_error(parent, s ? s : "error executing provider call", IN3_ERPC); } } From e5bd8e3e7be9827e1c6a777f66532a978f10791e Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Fri, 10 Sep 2021 13:51:15 +0200 Subject: [PATCH 048/101] fix qemu tests --- c/test/qemu/esp32/main/CMakeLists.txt | 1 + c/test/qemu/zephyr-arm3/CMakeLists.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/c/test/qemu/esp32/main/CMakeLists.txt b/c/test/qemu/esp32/main/CMakeLists.txt index f15b3f30c..b13b35da5 100644 --- a/c/test/qemu/esp32/main/CMakeLists.txt +++ b/c/test/qemu/esp32/main/CMakeLists.txt @@ -8,6 +8,7 @@ ADD_DEFINITIONS(-DETH_FULL) ADD_DEFINITIONS(-DIN3_LIB) ADD_DEFINITIONS(-DEVM_GAS) ADD_DEFINITIONS(-DLOGGING) +ADD_DEFINITIONS(-DCRYPTO_LIB) ADD_DEFINITIONS(-DNODESELECT_DEF) ADD_DEFINITIONS(-DNODESELECT_DEF_WL) ADD_DEFINITIONS(-DNO_BOOT_NODES_MAINNET) diff --git a/c/test/qemu/zephyr-arm3/CMakeLists.txt b/c/test/qemu/zephyr-arm3/CMakeLists.txt index 1d640a4b8..dcb69a5f1 100644 --- a/c/test/qemu/zephyr-arm3/CMakeLists.txt +++ b/c/test/qemu/zephyr-arm3/CMakeLists.txt @@ -9,6 +9,7 @@ target_sources(app PRIVATE src/main.c) ADD_DEFINITIONS(-DTEST) ADD_DEFINITIONS(-DDEBUG) +ADD_DEFINITIONS(-DCRYPTO_LIB) ADD_DEFINITIONS(-DNODESELECT_DEF) ADD_DEFINITIONS(-DNO_BOOT_NODES_MAINNET) ADD_DEFINITIONS(-DNO_BOOT_NODES_IPFS) From bc7e4b40c8385e98ae0cb65c7cf7ddd44669cb7b Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Mon, 13 Sep 2021 13:06:02 +0200 Subject: [PATCH 049/101] fixx parsing arguments --- c/src/cmd/in3/helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/c/src/cmd/in3/helper.c b/c/src/cmd/in3/helper.c index 697ba7d71..c7d23f01d 100644 --- a/c/src/cmd/in3/helper.c +++ b/c/src/cmd/in3/helper.c @@ -165,7 +165,7 @@ bool configure_arg(in3_t* c, char** args, int* index, int argc) { value++; name = alloca(value - arg - 2); strncpy(name, arg + 2, value - arg - 3); - name[value - arg - 1] = 0; + name[value - arg - 3] = 0; } else { name = alloca(strlen(arg) - 1); From baff893e981523daecdbe729aeab373d0c6421d0 Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Mon, 13 Sep 2021 13:06:19 +0200 Subject: [PATCH 050/101] fix cmake options --- c/options.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/c/options.cmake b/c/options.cmake index f7178d4ff..99f1016ec 100644 --- a/c/options.cmake +++ b/c/options.cmake @@ -91,7 +91,7 @@ ENDIF (PK_SIGNER) IF (CORE_API AND IN3API) set(IN3_API ${IN3_API} core_api) -ENDIF (CORE_API) +ENDIF (CORE_API AND IN3API) if (USE_PRECOMPUTED_EC) ADD_DEFINITIONS(-DUSE_PRECOMPUTED_CP=1) From 7c21ee05335c62379601959530787b2e3f50ae07 Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Mon, 13 Sep 2021 13:06:40 +0200 Subject: [PATCH 051/101] allow empty responses for raw_http --- c/src/core/client/execute.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/c/src/core/client/execute.c b/c/src/core/client/execute.c index 7e5f49607..b50c03ef4 100644 --- a/c/src/core/client/execute.c +++ b/c/src/core/client/execute.c @@ -263,7 +263,6 @@ NONULL static in3_ret_t ctx_create_payload(in3_req_t* c, sb_t* sb, bool no_in3) NONULL static in3_ret_t ctx_parse_response(in3_req_t* ctx, char* response_data, int len) { assert_in3_req(ctx); assert(response_data); - assert(len); const bool is_json = response_data[0] == '{' || response_data[0] == '[' || response_data[0] == '"'; if (is_raw_http(ctx)) { @@ -281,6 +280,9 @@ NONULL static in3_ret_t ctx_parse_response(in3_req_t* ctx, char* response_data, ctx->responses[0] = ctx->response_context->result; return IN3_OK; } + else { + assert(len); + } ctx->response_context = is_json ? parse_json(response_data) : parse_binary_str(response_data, len); @@ -386,7 +388,7 @@ static in3_ret_t verify_response(in3_req_t* ctx, in3_chain_t* chain, node_match_ in3_ret_t res = IN3_OK; - if (response->state || !response->data.len) // reponse has an error + if (response->state || (!is_raw_http(ctx) && !response->data.len)) // reponse has an error return handle_error_response(ctx, node, response); // we need to clean up the previos responses if set From 1f1d4bbb269afda81c3c59c844b142160847db53 Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Mon, 13 Sep 2021 19:38:57 +0200 Subject: [PATCH 052/101] fix escaped string when creating json --- c/src/core/util/data.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/c/src/core/util/data.c b/c/src/core/util/data.c index b285366b5..e8dd9c560 100644 --- a/c/src/core/util/data.c +++ b/c/src/core/util/data.c @@ -752,13 +752,13 @@ char* d_create_json(json_ctx_t* ctx, d_token_t* item) { return dst; case T_NULL: return _strdupn("null", 4); - case T_STRING: - dst = _malloc(l + 3); - dst[0] = '"'; - dst[l + 1] = '"'; - dst[l + 2] = 0; - memcpy(dst + 1, item->data, l); - return dst; + case T_STRING: { + sb_t sb = {.allocted = l + 1, .len = 0, .data = _malloc(l + 3)}; + sb_add_char(&sb, '"'); + sb_add_escaped_chars(&sb, (char*) item->data); + sb_add_char(&sb, '"'); + return sb.data; + } case T_BYTES: dst = _malloc(l * 2 + 5); dst[0] = '"'; From effe32380dc5b2e474916342b0e7755472665f1c Mon Sep 17 00:00:00 2001 From: chirag-parmar Date: Tue, 14 Sep 2021 14:38:32 +0200 Subject: [PATCH 053/101] add vade to shared libaries --- c/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/c/CMakeLists.txt b/c/CMakeLists.txt index 6ccf7e9d8..7aad53b1a 100644 --- a/c/CMakeLists.txt +++ b/c/CMakeLists.txt @@ -119,6 +119,10 @@ if (IN3_LIB) target_link_libraries(in3_lib zk_crypto_rs ) endif() + if (VADE) + target_link_libraries(in3_lib vade_evan ) + endif() + # install INSTALL(TARGETS in3_lib From 02fb85ad9c3cfb4364ddf936b9673dc5851bf672 Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Tue, 14 Sep 2021 19:24:51 +0200 Subject: [PATCH 054/101] add printx --- c/include/in3/plugin.h | 14 ++++++++ c/include/in3/request.h | 31 ++++++++++++++++++ c/include/in3/scache.h | 13 ++++---- c/include/in3/stringbuilder.h | 17 +++++----- c/include/in3/swift.h | 58 +++++++++++++++++++++++++++++++++ c/src/core/client/request.h | 31 ++++++++++++++++++ c/src/core/util/stringbuilder.c | 38 +++++++++++++++++++++ c/src/core/util/stringbuilder.h | 1 + 8 files changed, 189 insertions(+), 14 deletions(-) create mode 100644 c/include/in3/swift.h diff --git a/c/include/in3/plugin.h b/c/include/in3/plugin.h index f6412397b..4ee22f8d8 100644 --- a/c/include/in3/plugin.h +++ b/c/include/in3/plugin.h @@ -562,6 +562,20 @@ typedef struct { } \ } +/** + * sets the string as taken from the given property to the target and raises an error if the len does not fit. + */ +#define CNF_SET_STRING(dst, token, property) \ + { \ + const d_token_t* t = d_get(token, key(property)); \ + if (d_type(t) != T_NULL && d_type(t) != T_STRING) CNF_ERROR("Invalid config for " property "!") \ + const char* tmp = d_string(t); \ + if (tmp) { \ + if (dst) _free(dst); \ + dst = _strdupn(tmp, -1); \ + } \ + } + #ifdef __cplusplus } #endif diff --git a/c/include/in3/request.h b/c/include/in3/request.h index 1a367890d..01af7aba4 100644 --- a/c/include/in3/request.h +++ b/c/include/in3/request.h @@ -462,6 +462,37 @@ NONULL in3_proof_t in3_req_get_proof( int i /**< [in] the index within the request. */ ); +#define TRY_SUB_REQUEST(req, name, res, fmt, ...) \ + { \ + sb_t sb = {0}; \ + sb_printx(&sb, fmt, __VA_ARGS__); \ + in3_ret_t r = req_send_sub_request(req, name, sb.data, NULL, res, NULL); \ + _free(sb.data); \ + if (r) return r; \ + } + +#define TRY_CATCH_SUB_REQUEST(req, name, res, _catch, fmt, ...) \ + { \ + sb_t sb = {0}; \ + sb_printx(&sb, fmt, __VA_ARGS__); \ + in3_ret_t r = req_send_sub_request(req, name, sb.data, NULL, res, NULL); \ + _free(sb.data); \ + if (r) { \ + _catch; \ + return r; \ + } \ + } +#define TRY_FINAL_SUB_REQUEST(req, name, res, _catch, fmt, ...) \ + { \ + sb_t sb = {0}; \ + sb_printx(&sb, fmt, __VA_ARGS__); \ + in3_ret_t r = req_send_sub_request(req, name, sb.data, NULL, res, NULL); \ + _free(sb.data); \ + _catch; \ + if (r) \ + return r; \ + } + #ifdef __cplusplus } #endif diff --git a/c/include/in3/scache.h b/c/include/in3/scache.h index d6024f7d8..deeb17d21 100644 --- a/c/include/in3/scache.h +++ b/c/include/in3/scache.h @@ -50,12 +50,13 @@ extern "C" { #include typedef enum cache_props { - CACHE_PROP_MUST_FREE = 0x1, /**< indicates the content must be freed*/ - CACHE_PROP_SRC_REQ = 0x2, /**< the value holds the src-request */ - CACHE_PROP_ONLY_EXTERNAL = 0x4, /**< should only be freed if the context is external */ - CACHE_PROP_JSON = 0x8, /**< indicates the content is a json_ctxt and must be freed as such*/ - CACHE_PROP_INHERIT = 0x10, /**< indicates the content will be inherited when creating sub_request*/ - CACHE_PROP_PAYMENT = 0x80 /**< This cache-entry is a payment.data */ + CACHE_PROP_MUST_FREE = 0x1, /**< indicates the content must be freed*/ + CACHE_PROP_SRC_REQ = 0x2, /**< the value holds the src-request */ + CACHE_PROP_ONLY_EXTERNAL = 0x4, /**< should only be freed if the context is external */ + CACHE_PROP_ONLY_NOT_EXTERNAL = 0x20, /**< should only be freed if the context is not external */ + CACHE_PROP_JSON = 0x8, /**< indicates the content is a json_ctxt and must be freed as such*/ + CACHE_PROP_INHERIT = 0x10, /**< indicates the content will be inherited when creating sub_request*/ + CACHE_PROP_PAYMENT = 0x80 /**< This cache-entry is a payment.data */ } cache_props_t; /** * represents a single cache entry in a linked list. diff --git a/c/include/in3/stringbuilder.h b/c/include/in3/stringbuilder.h index 140623d05..d19bc114c 100644 --- a/c/include/in3/stringbuilder.h +++ b/c/include/in3/stringbuilder.h @@ -71,25 +71,26 @@ typedef struct sb { */ NONULL static inline sb_t sb_stack(char* p) { return (sb_t){.allocted = 0xffffff, .len = 0, .data = p}; } -sb_t* sb_new(const char* chars); /**< creates a new stringbuilder and copies the inital characters into it.*/ -NONULL sb_t* sb_init(sb_t* sb); /**< initializes a stringbuilder by allocating memory. */ -NONULL void sb_free(sb_t* sb); /**< frees all resources of the stringbuilder */ +sb_t* sb_new(const char* chars); /**< creates a new stringbuilder and copies the inital characters into it.*/ +NONULL sb_t* sb_init(sb_t* sb); /**< initializes a stringbuilder by allocating memory. */ +NONULL void sb_free(sb_t* sb); /**< frees all resources of the stringbuilder */ NONULL sb_t* sb_add_char(sb_t* sb, char c); /**< add a single character */ NONULL sb_t* sb_add_chars(sb_t* sb, const char* chars); /**< adds a string */ NONULL sb_t* sb_add_range(sb_t* sb, const char* chars, int start, int len); /**< add a string range */ NONULL sb_t* sb_add_key_value(sb_t* sb, const char* key, const char* value, int value_len, bool as_string); /**< adds a value with an optional key. if as_string is true the value will be quoted. */ NONULL_FOR((1, 3)) -sb_t* sb_add_bytes(sb_t* sb, const char* prefix, const bytes_t* bytes, int len, bool as_array); /**< add bytes as 0x-prefixed hexcoded string (including an optional prefix), if len>1 is passed bytes maybe an array ( if as_array==true) */ -NONULL sb_t* sb_add_hexuint_l(sb_t* sb, uintmax_t uint, size_t l); /**< add a integer value as hexcoded, 0x-prefixed string*/ -NONULL sb_t* sb_add_escaped_chars(sb_t* sb, const char* chars); /**< add chars but escapes all quotes */ -NONULL sb_t* sb_add_int(sb_t* sb, int64_t val); /**< adds a numeric value to the stringbuilder */ -NONULL char* format_json(const char* json); /**< format a json string and returns a new string, which needs to be freed */ +sb_t* sb_add_bytes(sb_t* sb, const char* prefix, const bytes_t* bytes, int len, bool as_array); /**< add bytes as 0x-prefixed hexcoded string (including an optional prefix), if len>1 is passed bytes maybe an array ( if as_array==true) */ +NONULL sb_t* sb_add_hexuint_l(sb_t* sb, uintmax_t uint, size_t l); /**< add a integer value as hexcoded, 0x-prefixed string*/ +NONULL sb_t* sb_add_escaped_chars(sb_t* sb, const char* chars); /**< add chars but escapes all quotes */ +NONULL sb_t* sb_add_int(sb_t* sb, int64_t val); /**< adds a numeric value to the stringbuilder */ +NONULL char* format_json(const char* json); /**< format a json string and returns a new string, which needs to be freed */ NONULL_FOR((1)) sb_t* sb_add_rawbytes(sb_t* sb, char* prefix, bytes_t b, int fix_size); sb_t* sb_print(sb_t* sb, const char* fmt, ...); sb_t* sb_vprint(sb_t* sb, const char* fmt, va_list args); sb_t* sb_add_json(sb_t* sb, const char* prefix, d_token_t* token); +sb_t* sb_printx(sb_t* sb, const char* fmt, ...); #ifdef __cplusplus } diff --git a/c/include/in3/swift.h b/c/include/in3/swift.h new file mode 100644 index 000000000..ee566b2d2 --- /dev/null +++ b/c/include/in3/swift.h @@ -0,0 +1,58 @@ +/******************************************************************************* + * This file is part of the Incubed project. + * Sources: https://github.com/slockit/in3-c + * + * Copyright (C) 2018-2020 slock.it GmbH, Blockchains LLC + * + * + * COMMERCIAL LICENSE USAGE + * + * Licensees holding a valid commercial license may use this file in accordance + * with the commercial license agreement provided with the Software or, alternatively, + * in accordance with the terms contained in a written agreement between you and + * slock.it GmbH/Blockchains LLC. For licensing terms and conditions or further + * information please contact slock.it at in3@slock.it. + * + * Alternatively, this file may be used under the AGPL license as follows: + * + * AGPL LICENSE USAGE + * + * This program is free software: you can redistribute it and/or modify it under the + * terms of the GNU Affero General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. + * [Permissions of this strong copyleft license are conditioned on making available + * complete source code of licensed works and modifications, which include larger + * works using a licensed work, under the same license. Copyright and license notices + * must be preserved. Contributors provide an express grant of patent rights.] + * You should have received a copy of the GNU Affero General Public License along + * with this program. If not, see . + *******************************************************************************/ +// @PUBLIC_HEADER +#ifndef IN3_SWIFT_H +#define IN3_SWIFT_H +#ifdef __clang__ +#define _NONULL _Nonnull +#else +#define _NONULL +#endif +#include "plugin.h" + +typedef struct in3_swift_cb { + in3_ret_t (*_NONULL cache_get)(in3_cache_ctx_t* _Nonnull ctx); + in3_ret_t (*_NONULL cache_set)(in3_cache_ctx_t* _Nonnull ctx); + in3_ret_t (*_NONULL cache_clear)(); + char* (*_NONULL sign_accounts)(in3_sign_account_ctx_t* _Nonnull ctx); +} swift_cb_t; + +in3_ret_t in3_register_swift(in3_t* _NONULL c, swift_cb_t* _NONULL cbs); + +char* sign_get_method(in3_req_t* r); +bytes_t sign_get_message(in3_req_t* r); +uint8_t* sign_get_from(in3_req_t* r); +int sign_get_payload_type(in3_req_t* r); +char* sign_get_metadata(in3_req_t* r); +#endif // IN3_SWIFT_H diff --git a/c/src/core/client/request.h b/c/src/core/client/request.h index 5d1fec423..b3db3c78f 100644 --- a/c/src/core/client/request.h +++ b/c/src/core/client/request.h @@ -462,6 +462,37 @@ NONULL in3_proof_t in3_req_get_proof( int i /**< [in] the index within the request. */ ); +#define TRY_SUB_REQUEST(req, name, res, fmt, ...) \ + { \ + sb_t sb = {0}; \ + sb_printx(&sb, fmt, __VA_ARGS__); \ + in3_ret_t r = req_send_sub_request(req, name, sb.data, NULL, res, NULL); \ + _free(sb.data); \ + if (r) return r; \ + } + +#define TRY_CATCH_SUB_REQUEST(req, name, res, _catch, fmt, ...) \ + { \ + sb_t sb = {0}; \ + sb_printx(&sb, fmt, __VA_ARGS__); \ + in3_ret_t r = req_send_sub_request(req, name, sb.data, NULL, res, NULL); \ + _free(sb.data); \ + if (r) { \ + _catch; \ + return r; \ + } \ + } +#define TRY_FINAL_SUB_REQUEST(req, name, res, _catch, fmt, ...) \ + { \ + sb_t sb = {0}; \ + sb_printx(&sb, fmt, __VA_ARGS__); \ + in3_ret_t r = req_send_sub_request(req, name, sb.data, NULL, res, NULL); \ + _free(sb.data); \ + _catch; \ + if (r) \ + return r; \ + } + #ifdef __cplusplus } #endif diff --git a/c/src/core/util/stringbuilder.c b/c/src/core/util/stringbuilder.c index 6010a61e2..8c6a47460 100644 --- a/c/src/core/util/stringbuilder.c +++ b/c/src/core/util/stringbuilder.c @@ -320,4 +320,42 @@ sb_t* sb_add_json(sb_t* sb, const char* prefix, d_token_t* token) { return sb_add_chars(sb, "null"); } return sb; +} + +sb_t* sb_printx(sb_t* sb, const char* fmt, ...) { + va_list args; + va_start(args, fmt); + for (const char* c = fmt; *c; c++) { + if (*c == '%') { + c++; + switch (*c) { + case 's': + sb_add_chars(sb, va_arg(args, char*)); + break; + case 'S': + sb_add_escaped_chars(sb, va_arg(args, char*)); + break; + case 'i': + case 'd': + case 'u': + sb_add_int(sb, va_arg(args, int64_t)); + break; + case 'b': + sb_add_rawbytes(sb, "", va_arg(args, bytes_t), 0); + break; + case 'j': + sb_add_json(sb, "", va_arg(args, d_token_t*)); + break; + case 0: + va_end(args); + return sb; + default: + break; + } + continue; + } + sb_add_char(sb, *c); + } + va_end(args); + return sb; } \ No newline at end of file diff --git a/c/src/core/util/stringbuilder.h b/c/src/core/util/stringbuilder.h index 140623d05..1ca0e5ad5 100644 --- a/c/src/core/util/stringbuilder.h +++ b/c/src/core/util/stringbuilder.h @@ -90,6 +90,7 @@ sb_t* sb_add_rawbytes(sb_t* sb, char* prefix, bytes_t b, int fix_size); sb_t* sb_print(sb_t* sb, const char* fmt, ...); sb_t* sb_vprint(sb_t* sb, const char* fmt, va_list args); sb_t* sb_add_json(sb_t* sb, const char* prefix, d_token_t* token); +sb_t* sb_printx(sb_t* sb, const char* fmt, ...); #ifdef __cplusplus } From 92352799b016946c7426825d3e657323f95054fb Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Wed, 15 Sep 2021 13:09:03 +0200 Subject: [PATCH 055/101] fix segfault --- c/src/core/util/stringbuilder.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/c/src/core/util/stringbuilder.c b/c/src/core/util/stringbuilder.c index 8c6a47460..8614cff81 100644 --- a/c/src/core/util/stringbuilder.c +++ b/c/src/core/util/stringbuilder.c @@ -92,7 +92,7 @@ sb_t* sb_add_escaped_chars(sb_t* sb, const char* chars) { int escapes = 0; if (l == 0 || chars == NULL) return sb; for (int i = 0; i < l; i++) { - if (chars[i] == '"' || chars[i] == '\n') escapes++; + if (chars[i] == '"' || chars[i] == '\n' || chars[i] == '\\') escapes++; } check_size(sb, l + escapes); memcpy(sb->data + sb->len, chars, l); @@ -323,6 +323,7 @@ sb_t* sb_add_json(sb_t* sb, const char* prefix, d_token_t* token) { } sb_t* sb_printx(sb_t* sb, const char* fmt, ...) { + check_size(sb, strlen(fmt)); va_list args; va_start(args, fmt); for (const char* c = fmt; *c; c++) { @@ -343,6 +344,9 @@ sb_t* sb_printx(sb_t* sb, const char* fmt, ...) { case 'b': sb_add_rawbytes(sb, "", va_arg(args, bytes_t), 0); break; + case 'v': + sb_add_rawbytes(sb, "", va_arg(args, bytes_t), -1); + break; case 'j': sb_add_json(sb, "", va_arg(args, d_token_t*)); break; @@ -354,8 +358,10 @@ sb_t* sb_printx(sb_t* sb, const char* fmt, ...) { } continue; } - sb_add_char(sb, *c); + if (sb->len + 1 >= sb->allocted) check_size(sb, 1); + sb->data[sb->len++] = *c; } va_end(args); + sb->data[sb->len] = 0; return sb; } \ No newline at end of file From fcd28898c2e563a00556aa3afbd7eccf51e786d5 Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Wed, 15 Sep 2021 14:48:47 +0200 Subject: [PATCH 056/101] update includes --- c/include/in3/stringbuilder.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/c/include/in3/stringbuilder.h b/c/include/in3/stringbuilder.h index d19bc114c..1ca0e5ad5 100644 --- a/c/include/in3/stringbuilder.h +++ b/c/include/in3/stringbuilder.h @@ -71,20 +71,20 @@ typedef struct sb { */ NONULL static inline sb_t sb_stack(char* p) { return (sb_t){.allocted = 0xffffff, .len = 0, .data = p}; } -sb_t* sb_new(const char* chars); /**< creates a new stringbuilder and copies the inital characters into it.*/ -NONULL sb_t* sb_init(sb_t* sb); /**< initializes a stringbuilder by allocating memory. */ -NONULL void sb_free(sb_t* sb); /**< frees all resources of the stringbuilder */ +sb_t* sb_new(const char* chars); /**< creates a new stringbuilder and copies the inital characters into it.*/ +NONULL sb_t* sb_init(sb_t* sb); /**< initializes a stringbuilder by allocating memory. */ +NONULL void sb_free(sb_t* sb); /**< frees all resources of the stringbuilder */ NONULL sb_t* sb_add_char(sb_t* sb, char c); /**< add a single character */ NONULL sb_t* sb_add_chars(sb_t* sb, const char* chars); /**< adds a string */ NONULL sb_t* sb_add_range(sb_t* sb, const char* chars, int start, int len); /**< add a string range */ NONULL sb_t* sb_add_key_value(sb_t* sb, const char* key, const char* value, int value_len, bool as_string); /**< adds a value with an optional key. if as_string is true the value will be quoted. */ NONULL_FOR((1, 3)) -sb_t* sb_add_bytes(sb_t* sb, const char* prefix, const bytes_t* bytes, int len, bool as_array); /**< add bytes as 0x-prefixed hexcoded string (including an optional prefix), if len>1 is passed bytes maybe an array ( if as_array==true) */ -NONULL sb_t* sb_add_hexuint_l(sb_t* sb, uintmax_t uint, size_t l); /**< add a integer value as hexcoded, 0x-prefixed string*/ -NONULL sb_t* sb_add_escaped_chars(sb_t* sb, const char* chars); /**< add chars but escapes all quotes */ -NONULL sb_t* sb_add_int(sb_t* sb, int64_t val); /**< adds a numeric value to the stringbuilder */ -NONULL char* format_json(const char* json); /**< format a json string and returns a new string, which needs to be freed */ +sb_t* sb_add_bytes(sb_t* sb, const char* prefix, const bytes_t* bytes, int len, bool as_array); /**< add bytes as 0x-prefixed hexcoded string (including an optional prefix), if len>1 is passed bytes maybe an array ( if as_array==true) */ +NONULL sb_t* sb_add_hexuint_l(sb_t* sb, uintmax_t uint, size_t l); /**< add a integer value as hexcoded, 0x-prefixed string*/ +NONULL sb_t* sb_add_escaped_chars(sb_t* sb, const char* chars); /**< add chars but escapes all quotes */ +NONULL sb_t* sb_add_int(sb_t* sb, int64_t val); /**< adds a numeric value to the stringbuilder */ +NONULL char* format_json(const char* json); /**< format a json string and returns a new string, which needs to be freed */ NONULL_FOR((1)) sb_t* sb_add_rawbytes(sb_t* sb, char* prefix, bytes_t b, int fix_size); sb_t* sb_print(sb_t* sb, const char* fmt, ...); From 99e705c13d43edf409aeb414f60ae128e644cc49 Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Wed, 15 Sep 2021 15:47:19 +0200 Subject: [PATCH 057/101] fix segfault --- c/src/core/util/stringbuilder.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/c/src/core/util/stringbuilder.c b/c/src/core/util/stringbuilder.c index 8614cff81..69134dc0c 100644 --- a/c/src/core/util/stringbuilder.c +++ b/c/src/core/util/stringbuilder.c @@ -60,7 +60,7 @@ sb_t* sb_init(sb_t* sb) { return sb; } NONULL static void check_size(sb_t* sb, size_t len) { - if (len == 0 || sb->len + len < sb->allocted) return; + if ((len == 0 || sb->len + len < sb->allocted) && sb->data) return; if (sb->allocted == 0) { sb->allocted = len + 1, sb->data = _malloc(sb->allocted); @@ -364,4 +364,4 @@ sb_t* sb_printx(sb_t* sb, const char* fmt, ...) { va_end(args); sb->data[sb->len] = 0; return sb; -} \ No newline at end of file +} From eb505094be41cc27fbb5a52f946fcd61335d2eb3 Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Mon, 27 Sep 2021 22:39:53 +0200 Subject: [PATCH 058/101] add rlp_decode --- c/src/api/eth1/rpc.yml | 25 +++++++++++++++++++++++++ c/src/api/eth1/rpc_api.c | 29 +++++++++++++++++++++++++++++ scripts/_in3.sh | 1 + 3 files changed, 55 insertions(+) diff --git a/c/src/api/eth1/rpc.yml b/c/src/api/eth1/rpc.yml index 7e4e502e9..0a9982432 100644 --- a/c/src/api/eth1/rpc.yml +++ b/c/src/api/eth1/rpc.yml @@ -102,6 +102,31 @@ utils: - "0x1234567890123456789012345678901234567890" - "0x05" + in3_rlpDecode: + sync: true + descr: rlp decode the data + params: + data: + type: bytes + descr: input data + result: + type: any + array: true + descr: a array with the values after decodeing. The result is either a hex-string or an array. + example: + request: + - '0xf83b808508e1409836829c40a86161616135663833353262373034623139653362616338373262343866326537663639356662653681ff82bbbb018080' + response: + - "0x" + - "0x08e1409836" + - "0x9c40" + - "0x61616161356638333532623730346231396533626163383732623438663265376636393566626536" + - "0xff" + - "0xbbbb" + - "0x01" + - "0x" + - "0x" + in3_checksumAddress: sync: true descr: Will convert an upper or lowercase Ethereum address to a checksum address. (See [EIP55](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-55.md) ) diff --git a/c/src/api/eth1/rpc_api.c b/c/src/api/eth1/rpc_api.c index 737d2ce4f..e2c9965b5 100644 --- a/c/src/api/eth1/rpc_api.c +++ b/c/src/api/eth1/rpc_api.c @@ -101,6 +101,32 @@ static in3_ret_t in3_abiDecode(in3_rpc_handle_ctx_t* ctx) { return IN3_OK; } +static in3_ret_t rlp_decode_data(sb_t* sb, bytes_t data, int index) { + bytes_t dst = {0}; + int type = rlp_decode(&data, index, &dst); + if (type == 1) { + if (index) sb_add_char(sb, ','); + sb_add_bytes(sb, "", &dst, 1, false); + return IN3_OK; + } + else if (type == 2) { + if (index) sb_add_char(sb, ','); + sb_add_char(sb, '['); + data = dst; + for (int i = 0; rlp_decode_data(sb, data, i) == IN3_OK; i++) {} + sb_add_char(sb, ']'); + return IN3_OK; + } + return IN3_ELIMIT; +} + +static in3_ret_t in3_rlpDecode(in3_rpc_handle_ctx_t* ctx) { + bytes_t data = {0}; + TRY_PARAM_GET_REQUIRED_BYTES(data, ctx, 0, 1, 0) + rlp_decode_data(in3_rpc_handle_start(ctx), data, 0); + return in3_rpc_handle_finish(ctx); +} + static in3_ret_t in3_checkSumAddress(in3_rpc_handle_ctx_t* ctx) { CHECK_PARAM_ADDRESS(ctx->req, ctx->params, 0) if (d_len(ctx->params) > 2) return req_set_error(ctx->req, "must be max 2 arguments", IN3_EINVAL); @@ -722,6 +748,9 @@ static in3_ret_t handle_intern(void* pdata, in3_plugin_act_t action, void* plugi #if !defined(RPC_ONLY) || defined(RPC_IN3_ABIDECODE) TRY_RPC("in3_abiDecode", in3_abiDecode(ctx)) #endif +#if !defined(RPC_ONLY) || defined(RPC_IN3_RLPDECODE) + TRY_RPC("in3_rlpDecode", in3_rlpDecode(ctx)) +#endif #if !defined(RPC_ONLY) || defined(RPC_IN3_CHECKSUMADDRESS) TRY_RPC("in3_checksumAddress", in3_checkSumAddress(ctx)) #endif diff --git a/scripts/_in3.sh b/scripts/_in3.sh index 95ee77374..6b983ea71 100755 --- a/scripts/_in3.sh +++ b/scripts/_in3.sh @@ -68,6 +68,7 @@ subcmds=( 'in3_checksumAddress: Will convert an upper or lowercase Ethereum address to a checksum address
' 'in3_fromWei: converts a given uint (also as hex) with a wei-value into a specified unit ' 'in3_parse_tx_url: parse a ethereum-url based on EIP 681 (https://eips ' + 'in3_rlpDecode: rlp decode the data ' 'in3_toWei: converts the given value into wei ' 'keccak: Returns Keccak-256 (not the standardized SHA3-256) of the given data' 'net_version: Returns the current network id' From aa2c72cf32c5695d87a7c7fb90f52af5ba36ba4c Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Tue, 28 Sep 2021 12:18:28 +0200 Subject: [PATCH 059/101] refactored sign_with_pk --- c/src/api/eth1/rpc_api.c | 16 ++----------- c/src/signer/pk-signer/signer.c | 41 ++++++++++++++++++++------------- c/src/signer/pk-signer/signer.h | 4 ++++ 3 files changed, 31 insertions(+), 30 deletions(-) diff --git a/c/src/api/eth1/rpc_api.c b/c/src/api/eth1/rpc_api.c index e2c9965b5..04e46d947 100644 --- a/c/src/api/eth1/rpc_api.c +++ b/c/src/api/eth1/rpc_api.c @@ -585,20 +585,8 @@ static in3_ret_t in3_sign_data(in3_rpc_handle_ctx_t* ctx) { TRY(in3_plugin_execute_first(ctx->req, PLGN_ACT_SIGN, &sc)); } else if (sc.account.len == 32) { - sc.signature = bytes(_malloc(65), 65); - if (sc.type == SIGN_EC_RAW) - ecdsa_sign_digest(&secp256k1, pk->data, data.data, sc.signature.data, sc.signature.data + 64, NULL); - else if (strcmp(sig_type, "raw") == 0 || sc.type == SIGN_EC_HASH) - ecdsa_sign(&secp256k1, HASHER_SHA3K, pk->data, data.data, data.len, sc.signature.data, sc.signature.data + 64, NULL); - else if (sc.type == SIGN_EC_PREFIX) { - bytes32_t hash; - eth_create_prefixed_msg_hash(hash, data); - ecdsa_sign_digest(&secp256k1, pk->data, hash, sc.signature.data, sc.signature.data + 64, NULL); - } - else { - _free(sc.signature.data); - return req_set_error(ctx->req, "unsupported sigType", IN3_EINVAL); - } + sc.signature = sign_with_pk(pk->data, data, sc.type); + if (!sc.signature.data) return req_set_error(ctx->req, "unsupported sigType", IN3_EINVAL); } else return req_set_error(ctx->req, "Invalid private key! Must be either an address(20 byte) or an raw private key (32 byte)", IN3_EINVAL); diff --git a/c/src/signer/pk-signer/signer.c b/c/src/signer/pk-signer/signer.c index 0cba988b1..f133d393b 100644 --- a/c/src/signer/pk-signer/signer.c +++ b/c/src/signer/pk-signer/signer.c @@ -101,28 +101,37 @@ void eth_create_prefixed_msg_hash(bytes32_t dst, bytes_t msg) { keccak_Final(&kctx, dst); } +bytes_t sign_with_pk(bytes32_t pk, bytes_t data, d_signature_type_t type) { + bytes_t res = bytes(_malloc(65), 65); + switch (type) { + case SIGN_EC_RAW: + ec_sign_pk_raw(data.data, pk, res.data); + break; + + case SIGN_EC_PREFIX: { + bytes32_t hash; + eth_create_prefixed_msg_hash(hash, data); + ec_sign_pk_raw(hash, pk, res.data); + break; + } + case SIGN_EC_HASH: + ec_sign_pk_hash(data.data, data.len, pk, hasher_sha3k, res.data); + break; + default: + _free(res.data); + res = NULL_BYTES; + } + return res; +} + static in3_ret_t eth_sign_pk(void* data, in3_plugin_act_t action, void* action_ctx) { signer_key_t* k = data; switch (action) { case PLGN_ACT_SIGN: { in3_sign_ctx_t* ctx = action_ctx; if (ctx->account.len == 20 && memcmp(k->account, ctx->account.data, 20)) return IN3_EIGNORE; - ctx->signature = bytes(_malloc(65), 65); - switch (ctx->type) { - case SIGN_EC_RAW: - return ec_sign_pk_raw(ctx->message.data, k->pk, ctx->signature.data); - - case SIGN_EC_PREFIX: { - bytes32_t hash; - eth_create_prefixed_msg_hash(hash, ctx->message); - return ec_sign_pk_raw(hash, k->pk, ctx->signature.data); - } - case SIGN_EC_HASH: - return ec_sign_pk_hash(ctx->message.data, ctx->message.len, k->pk, hasher_sha3k, ctx->signature.data); - default: - _free(ctx->signature.data); - return IN3_ENOTSUP; - } + ctx->signature = sign_with_pk(k->pk, ctx->message, ctx->type); + return ctx->signature.data ? IN3_OK : IN3_ENOTSUP; } case PLGN_ACT_SIGN_ACCOUNT: { diff --git a/c/src/signer/pk-signer/signer.h b/c/src/signer/pk-signer/signer.h index efa941c83..06f23df40 100644 --- a/c/src/signer/pk-signer/signer.h +++ b/c/src/signer/pk-signer/signer.h @@ -45,6 +45,7 @@ extern "C" { #endif #include "../../core/client/client.h" +#include "../../core/client/plugin.h" typedef enum { hasher_sha2, @@ -90,6 +91,9 @@ in3_ret_t ec_sign_pk_raw(uint8_t* message, uint8_t* pk, uint8_t* dst); /** hashes the msg by adding the Ethereum Signed Message-Prefix */ void eth_create_prefixed_msg_hash(bytes32_t dst, bytes_t msg); + +/** signs with a pk bases on the type */ +bytes_t sign_with_pk(bytes32_t pk, bytes_t data, d_signature_type_t type); #ifdef __cplusplus } #endif From f067fe265cdca744ee07f746c571850a31e4b80c Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Tue, 28 Sep 2021 12:42:02 +0200 Subject: [PATCH 060/101] update .netcore-version --- .../CallSmartContractFunction/CallSmartContractFunction.csproj | 2 +- .../ConnectToEthereum/ConnectToEthereum.csproj | 2 +- dotnet/Examples/EnsResolver/EnsResolver/EnsResolver.csproj | 2 +- dotnet/Examples/Ipfs/Ipfs/Ipfs.csproj | 2 +- dotnet/Examples/Logs/Logs/Logs.csproj | 2 +- .../SendTransaction/SendTransaction/SendTransaction.csproj | 2 +- dotnet/In3/In3.csproj | 2 +- dotnet/Test/Test.csproj | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/dotnet/Examples/CallSmartContractFunction/CallSmartContractFunction/CallSmartContractFunction.csproj b/dotnet/Examples/CallSmartContractFunction/CallSmartContractFunction/CallSmartContractFunction.csproj index 0d622fb72..10d11ae76 100644 --- a/dotnet/Examples/CallSmartContractFunction/CallSmartContractFunction/CallSmartContractFunction.csproj +++ b/dotnet/Examples/CallSmartContractFunction/CallSmartContractFunction/CallSmartContractFunction.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp3.1 +# netcoreapp5.0 diff --git a/dotnet/Examples/ConnectToEthereum/ConnectToEthereum/ConnectToEthereum.csproj b/dotnet/Examples/ConnectToEthereum/ConnectToEthereum/ConnectToEthereum.csproj index c1ea2b2cb..aa44e144d 100644 --- a/dotnet/Examples/ConnectToEthereum/ConnectToEthereum/ConnectToEthereum.csproj +++ b/dotnet/Examples/ConnectToEthereum/ConnectToEthereum/ConnectToEthereum.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp3.1 + netcoreapp5.0 diff --git a/dotnet/Examples/EnsResolver/EnsResolver/EnsResolver.csproj b/dotnet/Examples/EnsResolver/EnsResolver/EnsResolver.csproj index 0e0951a61..a71e48a8f 100644 --- a/dotnet/Examples/EnsResolver/EnsResolver/EnsResolver.csproj +++ b/dotnet/Examples/EnsResolver/EnsResolver/EnsResolver.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp3.1 + netcoreapp5.0 diff --git a/dotnet/Examples/Ipfs/Ipfs/Ipfs.csproj b/dotnet/Examples/Ipfs/Ipfs/Ipfs.csproj index fa8152694..f52a13691 100644 --- a/dotnet/Examples/Ipfs/Ipfs/Ipfs.csproj +++ b/dotnet/Examples/Ipfs/Ipfs/Ipfs.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp3.1 + netcoreapp5.0 diff --git a/dotnet/Examples/Logs/Logs/Logs.csproj b/dotnet/Examples/Logs/Logs/Logs.csproj index c1ea2b2cb..aa44e144d 100644 --- a/dotnet/Examples/Logs/Logs/Logs.csproj +++ b/dotnet/Examples/Logs/Logs/Logs.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp3.1 + netcoreapp5.0 diff --git a/dotnet/Examples/SendTransaction/SendTransaction/SendTransaction.csproj b/dotnet/Examples/SendTransaction/SendTransaction/SendTransaction.csproj index 0d622fb72..6125f1fda 100644 --- a/dotnet/Examples/SendTransaction/SendTransaction/SendTransaction.csproj +++ b/dotnet/Examples/SendTransaction/SendTransaction/SendTransaction.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp3.1 + netcoreapp5.0 diff --git a/dotnet/In3/In3.csproj b/dotnet/In3/In3.csproj index b45255e0c..cca97cc82 100644 --- a/dotnet/In3/In3.csproj +++ b/dotnet/In3/In3.csproj @@ -1,6 +1,6 @@ - netcoreapp3.1 + netcoreapp5.0 true In3 true diff --git a/dotnet/Test/Test.csproj b/dotnet/Test/Test.csproj index 6570a2502..ea00f4fc3 100644 --- a/dotnet/Test/Test.csproj +++ b/dotnet/Test/Test.csproj @@ -1,7 +1,7 @@ - netcoreapp3.1 + netcoreapp5.0 false From 99201ca37713860033e06c5708d927a73cb06190 Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Tue, 28 Sep 2021 12:42:34 +0200 Subject: [PATCH 061/101] fix typo --- .../CallSmartContractFunction/CallSmartContractFunction.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/Examples/CallSmartContractFunction/CallSmartContractFunction/CallSmartContractFunction.csproj b/dotnet/Examples/CallSmartContractFunction/CallSmartContractFunction/CallSmartContractFunction.csproj index 10d11ae76..6125f1fda 100644 --- a/dotnet/Examples/CallSmartContractFunction/CallSmartContractFunction/CallSmartContractFunction.csproj +++ b/dotnet/Examples/CallSmartContractFunction/CallSmartContractFunction/CallSmartContractFunction.csproj @@ -2,7 +2,7 @@ Exe -# netcoreapp5.0 + netcoreapp5.0 From ba85077c7ba81e27e046f0a8b7759746daf9b206 Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Tue, 28 Sep 2021 13:05:19 +0200 Subject: [PATCH 062/101] update to net5.0 --- .../CallSmartContractFunction/CallSmartContractFunction.csproj | 2 +- .../ConnectToEthereum/ConnectToEthereum.csproj | 2 +- dotnet/Examples/EnsResolver/EnsResolver/EnsResolver.csproj | 2 +- dotnet/Examples/Ipfs/Ipfs/Ipfs.csproj | 2 +- dotnet/Examples/Logs/Logs/Logs.csproj | 2 +- .../SendTransaction/SendTransaction/SendTransaction.csproj | 2 +- dotnet/In3/In3.csproj | 2 +- dotnet/Test/Test.csproj | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/dotnet/Examples/CallSmartContractFunction/CallSmartContractFunction/CallSmartContractFunction.csproj b/dotnet/Examples/CallSmartContractFunction/CallSmartContractFunction/CallSmartContractFunction.csproj index 6125f1fda..e1dab1d50 100644 --- a/dotnet/Examples/CallSmartContractFunction/CallSmartContractFunction/CallSmartContractFunction.csproj +++ b/dotnet/Examples/CallSmartContractFunction/CallSmartContractFunction/CallSmartContractFunction.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp5.0 + net5.0 diff --git a/dotnet/Examples/ConnectToEthereum/ConnectToEthereum/ConnectToEthereum.csproj b/dotnet/Examples/ConnectToEthereum/ConnectToEthereum/ConnectToEthereum.csproj index aa44e144d..e70215f40 100644 --- a/dotnet/Examples/ConnectToEthereum/ConnectToEthereum/ConnectToEthereum.csproj +++ b/dotnet/Examples/ConnectToEthereum/ConnectToEthereum/ConnectToEthereum.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp5.0 + net5.0 diff --git a/dotnet/Examples/EnsResolver/EnsResolver/EnsResolver.csproj b/dotnet/Examples/EnsResolver/EnsResolver/EnsResolver.csproj index a71e48a8f..d2962f219 100644 --- a/dotnet/Examples/EnsResolver/EnsResolver/EnsResolver.csproj +++ b/dotnet/Examples/EnsResolver/EnsResolver/EnsResolver.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp5.0 + net5.0 diff --git a/dotnet/Examples/Ipfs/Ipfs/Ipfs.csproj b/dotnet/Examples/Ipfs/Ipfs/Ipfs.csproj index f52a13691..f845fbece 100644 --- a/dotnet/Examples/Ipfs/Ipfs/Ipfs.csproj +++ b/dotnet/Examples/Ipfs/Ipfs/Ipfs.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp5.0 + net5.0 diff --git a/dotnet/Examples/Logs/Logs/Logs.csproj b/dotnet/Examples/Logs/Logs/Logs.csproj index aa44e144d..e70215f40 100644 --- a/dotnet/Examples/Logs/Logs/Logs.csproj +++ b/dotnet/Examples/Logs/Logs/Logs.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp5.0 + net5.0 diff --git a/dotnet/Examples/SendTransaction/SendTransaction/SendTransaction.csproj b/dotnet/Examples/SendTransaction/SendTransaction/SendTransaction.csproj index 6125f1fda..e1dab1d50 100644 --- a/dotnet/Examples/SendTransaction/SendTransaction/SendTransaction.csproj +++ b/dotnet/Examples/SendTransaction/SendTransaction/SendTransaction.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp5.0 + net5.0 diff --git a/dotnet/In3/In3.csproj b/dotnet/In3/In3.csproj index cca97cc82..855ca7e5f 100644 --- a/dotnet/In3/In3.csproj +++ b/dotnet/In3/In3.csproj @@ -1,6 +1,6 @@ - netcoreapp5.0 + net5.0 true In3 true diff --git a/dotnet/Test/Test.csproj b/dotnet/Test/Test.csproj index ea00f4fc3..dba057b6e 100644 --- a/dotnet/Test/Test.csproj +++ b/dotnet/Test/Test.csproj @@ -1,7 +1,7 @@ - netcoreapp5.0 + net5.0 false From 6cd72d2579ab2c91c2c77075700a59d866ce895c Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Tue, 28 Sep 2021 13:09:19 +0200 Subject: [PATCH 063/101] update docker --- dotnet/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dotnet/ci.yml b/dotnet/ci.yml index 9ec971008..9c9e42086 100644 --- a/dotnet/ci.yml +++ b/dotnet/ci.yml @@ -8,7 +8,7 @@ - if: '$CI_COMMIT_REF_PROTECTED == "true"' dotnet: - image: docker.slock.it/build-images/dotnet-core-sdk:3.1 + image: docker.slock.it/build-images/dotnet-sdk:5.0 stage: bindings needs: - mac_os @@ -62,7 +62,7 @@ dotnet_win: dotnet_linux: extends: - .dotnet_test - image: docker.slock.it/build-images/dotnet-core-sdk:3.1 + image: docker.slock.it/build-images/dotnet-sdk:5.0 tags: - short-jobs @@ -77,13 +77,13 @@ dotnet_arm: extends: - .dotnet_test - .only_dotnet - image: mcr.microsoft.com/dotnet/core/sdk:3.1 + image: mcr.microsoft.com/dotnet/sdk:5.0 tags: - arm release_nuget: stage: deploy - image: docker.slock.it/build-images/dotnet-core-sdk:3.1 + image: docker.slock.it/build-images/dotnet-sdk:5.0 tags: - short-jobs extends: .only_deploy From 6747769ecdaedc7672b31b38f07d6988104ce30a Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Thu, 30 Sep 2021 11:25:52 +0200 Subject: [PATCH 064/101] change const --- c/src/signer/pk-signer/signer.c | 2 +- c/src/signer/pk-signer/signer.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/c/src/signer/pk-signer/signer.c b/c/src/signer/pk-signer/signer.c index f133d393b..3c759d4f5 100644 --- a/c/src/signer/pk-signer/signer.c +++ b/c/src/signer/pk-signer/signer.c @@ -101,7 +101,7 @@ void eth_create_prefixed_msg_hash(bytes32_t dst, bytes_t msg) { keccak_Final(&kctx, dst); } -bytes_t sign_with_pk(bytes32_t pk, bytes_t data, d_signature_type_t type) { +bytes_t sign_with_pk(const bytes32_t pk, const bytes_t data, const d_signature_type_t type) { bytes_t res = bytes(_malloc(65), 65); switch (type) { case SIGN_EC_RAW: diff --git a/c/src/signer/pk-signer/signer.h b/c/src/signer/pk-signer/signer.h index 06f23df40..663ba3f61 100644 --- a/c/src/signer/pk-signer/signer.h +++ b/c/src/signer/pk-signer/signer.h @@ -93,7 +93,7 @@ in3_ret_t ec_sign_pk_raw(uint8_t* message, uint8_t* pk, uint8_t* dst); void eth_create_prefixed_msg_hash(bytes32_t dst, bytes_t msg); /** signs with a pk bases on the type */ -bytes_t sign_with_pk(bytes32_t pk, bytes_t data, d_signature_type_t type); +bytes_t sign_with_pk(const bytes32_t pk, const bytes_t data, const d_signature_type_t type); #ifdef __cplusplus } #endif From 831d49be76301c6413bb1f17f637953e15c9bf77 Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Fri, 1 Oct 2021 14:42:06 +0200 Subject: [PATCH 065/101] fixed const signing --- c/src/signer/pk-signer/signer.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/c/src/signer/pk-signer/signer.c b/c/src/signer/pk-signer/signer.c index 3c759d4f5..17396ff50 100644 --- a/c/src/signer/pk-signer/signer.c +++ b/c/src/signer/pk-signer/signer.c @@ -105,17 +105,26 @@ bytes_t sign_with_pk(const bytes32_t pk, const bytes_t data, const d_signature_t bytes_t res = bytes(_malloc(65), 65); switch (type) { case SIGN_EC_RAW: - ec_sign_pk_raw(data.data, pk, res.data); + if (ecdsa_sign_digest(&secp256k1, pk, data.data, res.data, res.data + 64, NULL) < 0) { + _free(res.data); + res = NULL_BYTES; + } break; case SIGN_EC_PREFIX: { bytes32_t hash; eth_create_prefixed_msg_hash(hash, data); - ec_sign_pk_raw(hash, pk, res.data); + if (ecdsa_sign_digest(&secp256k1, pk, hash, res.data, res.data + 64, NULL) < 0) { + _free(res.data); + res = NULL_BYTES; + } break; } case SIGN_EC_HASH: - ec_sign_pk_hash(data.data, data.len, pk, hasher_sha3k, res.data); + if (ecdsa_sign(&secp256k1, HASHER_SHA3K, pk, data.data, data.len, res.data, res.data + 64, NULL) < 0) { + _free(res.data); + res = NULL_BYTES; + } break; default: _free(res.data); From 4ba6a38fcd68d7dbf586258ee59288b866e37a4f Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Fri, 1 Oct 2021 14:49:38 +0200 Subject: [PATCH 066/101] use sign_with_pk for wasm --- wasm/src/wasm.c | 39 ++++++++------------------------------- 1 file changed, 8 insertions(+), 31 deletions(-) diff --git a/wasm/src/wasm.c b/wasm/src/wasm.c index 89c4b4393..c9e4b1cec 100644 --- a/wasm/src/wasm.c +++ b/wasm/src/wasm.c @@ -41,6 +41,7 @@ #include "../../c/src/nodeselect/full/cache.h" #include "../../c/src/nodeselect/full/nodelist.h" #endif +#include "../../c/src/signer/pk-signer/signer.h" #include "../../c/src/third-party/crypto/ecdsa.h" #include "../../c/src/third-party/crypto/secp256k1.h" #include "../../c/src/third-party/crypto/sha2.h" @@ -534,38 +535,14 @@ uint8_t* EMSCRIPTEN_KEEPALIVE private_to_public(bytes32_t prv_key) { uint8_t* EMSCRIPTEN_KEEPALIVE ec_sign(bytes32_t pk, d_signature_type_t type, uint8_t* data, int len, bool adjust_v) { uint8_t* dst = malloc(65); #ifdef CRYPTO_LIB - int error = -1; - switch (type) { - case SIGN_EC_PREFIX: { - bytes32_t hash; - struct SHA3_CTX kctx; - sha3_256_Init(&kctx); - const char* PREFIX = "\x19" - "Ethereum Signed Message:\n"; - sha3_Update(&kctx, (uint8_t*) PREFIX, strlen(PREFIX)); - sha3_Update(&kctx, hash, sprintf((char*) hash, "%d", len)); - if (len) sha3_Update(&kctx, data, len); - keccak_Final(&kctx, hash); - error = ecdsa_sign_digest(&secp256k1, pk, hash, dst, dst + 64, NULL); - break; - } - case SIGN_EC_RAW: - error = ecdsa_sign_digest(&secp256k1, pk, data, dst, dst + 64, NULL); - break; - case SIGN_EC_HASH: - error = ecdsa_sign(&secp256k1, HASHER_SHA3K, pk, data, len, dst, dst + 64, NULL); - break; - - default: - error = -2; - } - if (error < 0) { - free(dst); - return NULL; - } - if (adjust_v) dst[64] += 27; + bytes_t sig = sign_with_pk(pk, bytes(data, len), type); + if (!sig.data) + in3_set_error("could not create signature"); + else if (adjust_v && sig.len == 65 && sig.data[64] < 26) + sig.data[64] += 27; + return sig.data; #else - in3_set_error("no cryptolib installer"); + in3_set_error("no cryptolib installed"); #endif return dst; } From ef0b04a6be1b235732f8a72694329f70775512fe Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Mon, 4 Oct 2021 13:51:28 +0200 Subject: [PATCH 067/101] add %x to printx --- c/src/core/util/stringbuilder.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/c/src/core/util/stringbuilder.c b/c/src/core/util/stringbuilder.c index 69134dc0c..a7e1d89d5 100644 --- a/c/src/core/util/stringbuilder.c +++ b/c/src/core/util/stringbuilder.c @@ -341,6 +341,9 @@ sb_t* sb_printx(sb_t* sb, const char* fmt, ...) { case 'u': sb_add_int(sb, va_arg(args, int64_t)); break; + case 'x': + sb_add_hexuint_l(sb, va_arg(args, uint64_t), sizeof(uint64_t)); + break; case 'b': sb_add_rawbytes(sb, "", va_arg(args, bytes_t), 0); break; From b4ad524ddf432acded993da62e99f3a6721ac281 Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Thu, 7 Oct 2021 14:20:46 +0200 Subject: [PATCH 068/101] fix EVM_DEBUG --- c/src/verifier/eth1/evm/evm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/c/src/verifier/eth1/evm/evm.h b/c/src/verifier/eth1/evm/evm.h index 82a1a12e2..7e0634b2c 100644 --- a/c/src/verifier/eth1/evm/evm.h +++ b/c/src/verifier/eth1/evm/evm.h @@ -117,7 +117,7 @@ typedef enum evm_state { #if defined(DEBUG) #define EVM_DEBUG_BLOCK(_code_block_) \ - if (in3_log_level_is(LOG_TRACE)) (_code_block_) + if (in3_log_level_is(LOG_TRACE)) { _code_block_ } #else #define EVM_DEBUG_BLOCK(...) #endif From 56a225a384536c267d1fdc95e4e015f15a63262f Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Mon, 11 Oct 2021 15:45:57 +0200 Subject: [PATCH 069/101] fix double allocation --- c/src/core/util/bytes.c | 1 + 1 file changed, 1 insertion(+) diff --git a/c/src/core/util/bytes.c b/c/src/core/util/bytes.c index 8010f945b..48e0bc7d0 100644 --- a/c/src/core/util/bytes.c +++ b/c/src/core/util/bytes.c @@ -202,6 +202,7 @@ int bb_check_size(bytes_builder_t* bb, size_t len) { if (bb->b.data == NULL) { bb->b.data = _malloc(len); bb->bsize = len; + return 0; } #ifdef __ZEPHYR__ size_t l = bb->bsize; From 6451626197f3aac2c5070a7de1b42c17ff881c8f Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Tue, 12 Oct 2021 13:14:46 +0200 Subject: [PATCH 070/101] added BTC sign type --- c/src/api/eth1/rpc_api.c | 1 + c/src/core/client/client.h | 57 +++++++++++++++++---------------- c/src/core/client/plugin.h | 11 ++++++- c/src/core/client/request.c | 12 ++++++- c/src/signer/pk-signer/signer.c | 18 ++++++++++- 5 files changed, 68 insertions(+), 31 deletions(-) diff --git a/c/src/api/eth1/rpc_api.c b/c/src/api/eth1/rpc_api.c index 04e46d947..e5b43bbb8 100644 --- a/c/src/api/eth1/rpc_api.c +++ b/c/src/api/eth1/rpc_api.c @@ -580,6 +580,7 @@ static in3_ret_t in3_sign_data(in3_rpc_handle_ctx_t* ctx) { if (strcmp(sig_type, "sign_ec_hash") == 0) sc.type = SIGN_EC_HASH; if (strcmp(sig_type, "sign_ec_raw") == 0) sc.type = SIGN_EC_RAW; if (strcmp(sig_type, "sign_ec_prefix") == 0) sc.type = SIGN_EC_PREFIX; + if (strcmp(sig_type, "sign_ec_btc") == 0) sc.type = SIGN_EC_BTC; if ((sc.account.len == 20 || sc.account.len == 0) && in3_plugin_is_registered(ctx->req->client, PLGN_ACT_SIGN)) { TRY(in3_plugin_execute_first(ctx->req, PLGN_ACT_SIGN, &sc)); diff --git a/c/src/core/client/client.h b/c/src/core/client/client.h index 3264cddc9..53171186d 100644 --- a/c/src/core/client/client.h +++ b/c/src/core/client/client.h @@ -142,34 +142,35 @@ typedef struct in3_chain { /** plugin action list */ typedef enum { - PLGN_ACT_INIT = 0x1, /**< initialize plugin - use for allocating/setting-up internal resources . Plugins will be initialized before first used. The plgn_ctx will be the first request ctx in3_req_t */ - PLGN_ACT_TERM = 0x2, /**< terminate plugin - use for releasing internal resources and cleanup. */ - PLGN_ACT_TRANSPORT_SEND = 0x4, /**< sends out a request - the transport plugin will receive a request_t as plgn_ctx, it may set a cptr which will be passed back when fetching more responses. */ - PLGN_ACT_TRANSPORT_RECEIVE = 0x8, /**< fetch next response - the transport plugin will receive a request_t as plgn_ctx, which contains a cptr if set previously*/ - PLGN_ACT_TRANSPORT_CLEAN = 0x10, /**< free-up transport resources - the transport plugin will receive a request_t as plgn_ctx if the cptr was set.*/ - PLGN_ACT_SIGN_ACCOUNT = 0x20, /**< returns the default account of the signer */ - PLGN_ACT_SIGN_PREPARE = 0x40, /**< allows a wallet to manipulate the payload before signing - the plgn_ctx will be in3_sign_ctx_t. This way a tx can be send through a multisig */ - PLGN_ACT_SIGN = 0x80, /**< signs the payload - the plgn_ctx will be in3_sign_ctx_t. */ - PLGN_ACT_RPC_HANDLE = 0x100, /**< a plugin may respond to a rpc-request directly (without sending it to the node). */ - PLGN_ACT_RPC_VERIFY = 0x200, /**< verifies the response. the plgn_ctx will be a in3_vctx_t holding all data */ - PLGN_ACT_CACHE_SET = 0x400, /**< stores data to be reused later - the plgn_ctx will be a in3_cache_ctx_t containing the data */ - PLGN_ACT_CACHE_GET = 0x800, /**< reads data to be previously stored - the plgn_ctx will be a in3_cache_ctx_t containing the key. if the data was found the data-property needs to be set. */ - PLGN_ACT_CACHE_CLEAR = 0x1000, /**< clears all stored data - plgn_ctx will be NULL */ - PLGN_ACT_CONFIG_SET = 0x2000, /**< gets a config-token and reads data from it */ - PLGN_ACT_CONFIG_GET = 0x4000, /**< gets a string-builder and adds all config to it. */ - PLGN_ACT_PAY_PREPARE = 0x8000, /**< prepares a payment */ - PLGN_ACT_PAY_FOLLOWUP = 0x10000, /**< called after a request to update stats. */ - PLGN_ACT_PAY_HANDLE = 0x20000, /**< handles the payment */ - PLGN_ACT_PAY_SIGN_REQ = 0x40000, /**< signs a request */ - PLGN_ACT_LOG_ERROR = 0x80000, /**< report an error */ - PLGN_ACT_NL_PICK = 0x100000, /**< picks the data nodes, plgn_ctx will be a pointer to in3_req_t */ - PLGN_ACT_NL_PICK_FOLLOWUP = 0x200000, /**< called after receiving a response in order to decide whether a update is needed, plgn_ctx will be a pointer to in3_req_t */ - PLGN_ACT_NL_BLACKLIST = 0x400000, /**< blacklist a particular node in the nodelist, plgn_ctx will be a pointer to the node's address. */ - PLGN_ACT_NL_FAILABLE = 0x800000, /**< handle fail-able request, plgn_ctx will be a pointer to in3_req_t */ - PLGN_ACT_NL_OFFLINE = 0x1000000, /**< mark a particular node in the nodelist as offline, plgn_ctx will be a pointer to in3_nl_offline_ctx_t. */ - PLGN_ACT_CHAIN_CHANGE = 0x2000000, /**< chain id change event, called after setting new chain id */ - PLGN_ACT_GET_DATA = 0x4000000, /**< get access to plugin data as a void ptr */ - PLGN_ACT_ADD_PAYLOAD = 0x8000000, /**< add plugin specific metadata to payload, plgn_ctx will be a sb_t pointer, make sure to begin with a comma */ + PLGN_ACT_INIT = 0x1, /**< initialize plugin - use for allocating/setting-up internal resources . Plugins will be initialized before first used. The plgn_ctx will be the first request ctx in3_req_t */ + PLGN_ACT_TERM = 0x2, /**< terminate plugin - use for releasing internal resources and cleanup. ( ctx: in3_t )*/ + PLGN_ACT_TRANSPORT_SEND = 0x4, /**< sends out a request - the transport plugin will receive a request_t as plgn_ctx, it may set a cptr which will be passed back when fetching more responses. */ + PLGN_ACT_TRANSPORT_RECEIVE = 0x8, /**< fetch next response - the transport plugin will receive a request_t as plgn_ctx, which contains a cptr if set previously*/ + PLGN_ACT_TRANSPORT_CLEAN = 0x10, /**< free-up transport resources - the transport plugin will receive a request_t as plgn_ctx if the cptr was set.*/ + PLGN_ACT_SIGN_ACCOUNT = 0x20, /**< returns the accounts or addresses of the signer */ + PLGN_ACT_SIGN_PUBLICKEY = 0x40, /**< returns the public key for a given address ( ctx: in3_sign_public_key_ctx_t )*/ + PLGN_ACT_SIGN_PREPARE = 0x80, /**< allows a wallet to manipulate the payload before signing - the plgn_ctx will be in3_sign_ctx_t. This way a tx can be send through a multisig */ + PLGN_ACT_SIGN = 0x100, /**< signs the payload - the plgn_ctx will be in3_sign_ctx_t. */ + PLGN_ACT_RPC_HANDLE = 0x200, /**< a plugin may respond to a rpc-request directly (without sending it to the node). */ + PLGN_ACT_RPC_VERIFY = 0x400, /**< verifies the response. the plgn_ctx will be a in3_vctx_t holding all data */ + PLGN_ACT_CACHE_SET = 0x800, /**< stores data to be reused later - the plgn_ctx will be a in3_cache_ctx_t containing the data */ + PLGN_ACT_CACHE_GET = 0x1000, /**< reads data to be previously stored - the plgn_ctx will be a in3_cache_ctx_t containing the key. if the data was found the data-property needs to be set. */ + PLGN_ACT_CACHE_CLEAR = 0x2000, /**< clears all stored data - plgn_ctx will be NULL */ + PLGN_ACT_CONFIG_SET = 0x4000, /**< gets a config-token and reads data from it */ + PLGN_ACT_CONFIG_GET = 0x8000, /**< gets a string-builder and adds all config to it. */ + PLGN_ACT_PAY_PREPARE = 0x10000, /**< prepares a payment */ + PLGN_ACT_PAY_FOLLOWUP = 0x20000, /**< called after a request to update stats. */ + PLGN_ACT_PAY_HANDLE = 0x40000, /**< handles the payment */ + PLGN_ACT_PAY_SIGN_REQ = 0x80000, /**< signs a request */ + PLGN_ACT_LOG_ERROR = 0x100000, /**< report an error */ + PLGN_ACT_NL_PICK = 0x200000, /**< picks the data nodes, plgn_ctx will be a pointer to in3_req_t */ + PLGN_ACT_NL_PICK_FOLLOWUP = 0x400000, /**< called after receiving a response in order to decide whether a update is needed, plgn_ctx will be a pointer to in3_req_t */ + PLGN_ACT_NL_BLACKLIST = 0x800000, /**< blacklist a particular node in the nodelist, plgn_ctx will be a pointer to the node's address. */ + PLGN_ACT_NL_FAILABLE = 0x1000000, /**< handle fail-able request, plgn_ctx will be a pointer to in3_req_t */ + PLGN_ACT_NL_OFFLINE = 0x2000000, /**< mark a particular node in the nodelist as offline, plgn_ctx will be a pointer to in3_nl_offline_ctx_t. */ + PLGN_ACT_CHAIN_CHANGE = 0x4000000, /**< chain id change event, called after setting new chain id */ + PLGN_ACT_GET_DATA = 0x8000000, /**< get access to plugin data as a void ptr */ + PLGN_ACT_ADD_PAYLOAD = 0x10000000, /**< add plugin specific metadata to payload, plgn_ctx will be a sb_t pointer, make sure to begin with a comma */ } in3_plugin_act_t; /** diff --git a/c/src/core/client/plugin.h b/c/src/core/client/plugin.h index 4ee22f8d8..7adc2b339 100644 --- a/c/src/core/client/plugin.h +++ b/c/src/core/client/plugin.h @@ -257,7 +257,7 @@ typedef enum { SIGNER_EIP1271 = 2 } in3_signer_type_t; /** - * action context when retrieving the account of a signer. + * action context when retrieving the addresses or accounts of a signer. */ typedef struct sign_account_ctx { struct in3_req* req; /**< the context of the request in order report errors */ @@ -265,6 +265,14 @@ typedef struct sign_account_ctx { int accounts_len; /**< number of accounts */ in3_signer_type_t signer_type; /**< the type of the signer used for this account.*/ } in3_sign_account_ctx_t; +/** + * action context when retrieving the public key of the signer. + */ +typedef struct sign_public_key_ctx { + struct in3_req* req; /**< the context of the request in order report errors */ + uint8_t* account; /**< the account to use for the signature */ + uint8_t public_key[64]; /**< the public key in case the plugin returns IN3_OK */ +} in3_sign_public_key_ctx_t; // ----------- SIGN_PREPARE --------------- @@ -287,6 +295,7 @@ typedef enum { SIGN_EC_RAW = 0, /**< sign the data directly */ SIGN_EC_HASH = 1, /**< hash and sign the data */ SIGN_EC_PREFIX = 2, /**< add Ethereum Signed Message-Proefix, hash and sign the data */ + SIGN_EC_BTC = 3, /**< hashes the data twice with sha256 and signs it */ } d_signature_type_t; /** payload type of the requested signature. It describes how to deserialize the payload. */ diff --git a/c/src/core/client/request.c b/c/src/core/client/request.c index ee0c38f2d..8b9fe535a 100644 --- a/c/src/core/client/request.c +++ b/c/src/core/client/request.c @@ -427,6 +427,16 @@ in3_ret_t req_send_sub_request(in3_req_t* parent, char* method, char* params, ch return ret; } +static inline const char* method_for_sigtype(d_signature_type_t type) { + switch (type) { + case SIGN_EC_RAW: return "sign_ec_raw"; + case SIGN_EC_HASH: return "sign_ec_hash"; + case SIGN_EC_PREFIX: return "sign_ec_prefix"; + case SIGN_EC_BTC: return "sign_ec_btc"; + default: return "sign_ec_hash"; + } +} + in3_ret_t req_send_sign_request(in3_req_t* ctx, d_signature_type_t type, d_payload_type_t pl_type, bytes_t* signature, bytes_t raw_data, bytes_t from, d_token_t* meta, bytes_t cache_key) { bytes_t* cached_sig = in3_cache_get_entry(ctx->cache, &cache_key); @@ -436,7 +446,7 @@ in3_ret_t req_send_sign_request(in3_req_t* ctx, d_signature_type_t type, d_paylo } // get the signature from required - const char* method = type == SIGN_EC_HASH ? "sign_ec_hash" : (type == SIGN_EC_PREFIX ? "sign_ec_prefix" : "sign_ec_raw"); + const char* method = method_for_sigtype(type); sb_t params = {0}; sb_add_bytes(¶ms, "[", &raw_data, 1, false); sb_add_chars(¶ms, ","); diff --git a/c/src/signer/pk-signer/signer.c b/c/src/signer/pk-signer/signer.c index 17396ff50..3b3b52bde 100644 --- a/c/src/signer/pk-signer/signer.c +++ b/c/src/signer/pk-signer/signer.c @@ -126,6 +126,12 @@ bytes_t sign_with_pk(const bytes32_t pk, const bytes_t data, const d_signature_t res = NULL_BYTES; } break; + case SIGN_EC_BTC: + if (ecdsa_sign(&secp256k1, HASHER_SHA2D, pk, data.data, data.len, res.data, res.data + 64, NULL) < 0) { + _free(res.data); + res = NULL_BYTES; + } + break; default: _free(res.data); res = NULL_BYTES; @@ -153,6 +159,16 @@ static in3_ret_t eth_sign_pk(void* data, in3_plugin_act_t action, void* action_c return IN3_OK; } + case PLGN_ACT_SIGN_PUBLICKEY: { + // generate the address from the key + in3_sign_public_key_ctx_t* ctx = action_ctx; + if (ctx->account && memcmp(ctx->account, k->account, 20)) return IN3_EIGNORE; + uint8_t p[65]; + ecdsa_get_public_key65(&secp256k1, k->pk, p); + memcpy(ctx->public_key, p + 1, 64); + return IN3_OK; + } + case PLGN_ACT_TERM: { _free(k); return IN3_OK; @@ -168,7 +184,7 @@ in3_ret_t eth_set_pk_signer(in3_t* in3, bytes32_t pk) { signer_key_t* k = _malloc(sizeof(signer_key_t)); get_address(pk, k->account); memcpy(k->pk, pk, 32); - return in3_plugin_register(in3, PLGN_ACT_SIGN_ACCOUNT | PLGN_ACT_SIGN | PLGN_ACT_TERM, eth_sign_pk, k, false); + return in3_plugin_register(in3, PLGN_ACT_SIGN_ACCOUNT | PLGN_ACT_SIGN | PLGN_ACT_TERM | PLGN_ACT_SIGN_PUBLICKEY, eth_sign_pk, k, false); } static in3_ret_t add_raw_key(in3_rpc_handle_ctx_t* ctx) { From ec5b4cc23617b7670aafcf30d54ebca0399b0a99 Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Tue, 12 Oct 2021 13:34:40 +0200 Subject: [PATCH 071/101] update includes --- c/include/in3/client.h | 57 +++++++++++++++++++++--------------------- c/include/in3/plugin.h | 11 +++++++- c/include/in3/signer.h | 4 +++ 3 files changed, 43 insertions(+), 29 deletions(-) diff --git a/c/include/in3/client.h b/c/include/in3/client.h index 0845f9c83..3cfe09db9 100644 --- a/c/include/in3/client.h +++ b/c/include/in3/client.h @@ -142,34 +142,35 @@ typedef struct in3_chain { /** plugin action list */ typedef enum { - PLGN_ACT_INIT = 0x1, /**< initialize plugin - use for allocating/setting-up internal resources . Plugins will be initialized before first used. The plgn_ctx will be the first request ctx in3_req_t */ - PLGN_ACT_TERM = 0x2, /**< terminate plugin - use for releasing internal resources and cleanup. */ - PLGN_ACT_TRANSPORT_SEND = 0x4, /**< sends out a request - the transport plugin will receive a request_t as plgn_ctx, it may set a cptr which will be passed back when fetching more responses. */ - PLGN_ACT_TRANSPORT_RECEIVE = 0x8, /**< fetch next response - the transport plugin will receive a request_t as plgn_ctx, which contains a cptr if set previously*/ - PLGN_ACT_TRANSPORT_CLEAN = 0x10, /**< free-up transport resources - the transport plugin will receive a request_t as plgn_ctx if the cptr was set.*/ - PLGN_ACT_SIGN_ACCOUNT = 0x20, /**< returns the default account of the signer */ - PLGN_ACT_SIGN_PREPARE = 0x40, /**< allows a wallet to manipulate the payload before signing - the plgn_ctx will be in3_sign_ctx_t. This way a tx can be send through a multisig */ - PLGN_ACT_SIGN = 0x80, /**< signs the payload - the plgn_ctx will be in3_sign_ctx_t. */ - PLGN_ACT_RPC_HANDLE = 0x100, /**< a plugin may respond to a rpc-request directly (without sending it to the node). */ - PLGN_ACT_RPC_VERIFY = 0x200, /**< verifies the response. the plgn_ctx will be a in3_vctx_t holding all data */ - PLGN_ACT_CACHE_SET = 0x400, /**< stores data to be reused later - the plgn_ctx will be a in3_cache_ctx_t containing the data */ - PLGN_ACT_CACHE_GET = 0x800, /**< reads data to be previously stored - the plgn_ctx will be a in3_cache_ctx_t containing the key. if the data was found the data-property needs to be set. */ - PLGN_ACT_CACHE_CLEAR = 0x1000, /**< clears all stored data - plgn_ctx will be NULL */ - PLGN_ACT_CONFIG_SET = 0x2000, /**< gets a config-token and reads data from it */ - PLGN_ACT_CONFIG_GET = 0x4000, /**< gets a string-builder and adds all config to it. */ - PLGN_ACT_PAY_PREPARE = 0x8000, /**< prepares a payment */ - PLGN_ACT_PAY_FOLLOWUP = 0x10000, /**< called after a request to update stats. */ - PLGN_ACT_PAY_HANDLE = 0x20000, /**< handles the payment */ - PLGN_ACT_PAY_SIGN_REQ = 0x40000, /**< signs a request */ - PLGN_ACT_LOG_ERROR = 0x80000, /**< report an error */ - PLGN_ACT_NL_PICK = 0x100000, /**< picks the data nodes, plgn_ctx will be a pointer to in3_req_t */ - PLGN_ACT_NL_PICK_FOLLOWUP = 0x200000, /**< called after receiving a response in order to decide whether a update is needed, plgn_ctx will be a pointer to in3_req_t */ - PLGN_ACT_NL_BLACKLIST = 0x400000, /**< blacklist a particular node in the nodelist, plgn_ctx will be a pointer to the node's address. */ - PLGN_ACT_NL_FAILABLE = 0x800000, /**< handle fail-able request, plgn_ctx will be a pointer to in3_req_t */ - PLGN_ACT_NL_OFFLINE = 0x1000000, /**< mark a particular node in the nodelist as offline, plgn_ctx will be a pointer to in3_nl_offline_ctx_t. */ - PLGN_ACT_CHAIN_CHANGE = 0x2000000, /**< chain id change event, called after setting new chain id */ - PLGN_ACT_GET_DATA = 0x4000000, /**< get access to plugin data as a void ptr */ - PLGN_ACT_ADD_PAYLOAD = 0x8000000, /**< add plugin specific metadata to payload, plgn_ctx will be a sb_t pointer, make sure to begin with a comma */ + PLGN_ACT_INIT = 0x1, /**< initialize plugin - use for allocating/setting-up internal resources . Plugins will be initialized before first used. The plgn_ctx will be the first request ctx in3_req_t */ + PLGN_ACT_TERM = 0x2, /**< terminate plugin - use for releasing internal resources and cleanup. ( ctx: in3_t )*/ + PLGN_ACT_TRANSPORT_SEND = 0x4, /**< sends out a request - the transport plugin will receive a request_t as plgn_ctx, it may set a cptr which will be passed back when fetching more responses. */ + PLGN_ACT_TRANSPORT_RECEIVE = 0x8, /**< fetch next response - the transport plugin will receive a request_t as plgn_ctx, which contains a cptr if set previously*/ + PLGN_ACT_TRANSPORT_CLEAN = 0x10, /**< free-up transport resources - the transport plugin will receive a request_t as plgn_ctx if the cptr was set.*/ + PLGN_ACT_SIGN_ACCOUNT = 0x20, /**< returns the accounts or addresses of the signer */ + PLGN_ACT_SIGN_PUBLICKEY = 0x40, /**< returns the public key for a given address ( ctx: in3_sign_public_key_ctx_t )*/ + PLGN_ACT_SIGN_PREPARE = 0x80, /**< allows a wallet to manipulate the payload before signing - the plgn_ctx will be in3_sign_ctx_t. This way a tx can be send through a multisig */ + PLGN_ACT_SIGN = 0x100, /**< signs the payload - the plgn_ctx will be in3_sign_ctx_t. */ + PLGN_ACT_RPC_HANDLE = 0x200, /**< a plugin may respond to a rpc-request directly (without sending it to the node). */ + PLGN_ACT_RPC_VERIFY = 0x400, /**< verifies the response. the plgn_ctx will be a in3_vctx_t holding all data */ + PLGN_ACT_CACHE_SET = 0x800, /**< stores data to be reused later - the plgn_ctx will be a in3_cache_ctx_t containing the data */ + PLGN_ACT_CACHE_GET = 0x1000, /**< reads data to be previously stored - the plgn_ctx will be a in3_cache_ctx_t containing the key. if the data was found the data-property needs to be set. */ + PLGN_ACT_CACHE_CLEAR = 0x2000, /**< clears all stored data - plgn_ctx will be NULL */ + PLGN_ACT_CONFIG_SET = 0x4000, /**< gets a config-token and reads data from it */ + PLGN_ACT_CONFIG_GET = 0x8000, /**< gets a string-builder and adds all config to it. */ + PLGN_ACT_PAY_PREPARE = 0x10000, /**< prepares a payment */ + PLGN_ACT_PAY_FOLLOWUP = 0x20000, /**< called after a request to update stats. */ + PLGN_ACT_PAY_HANDLE = 0x40000, /**< handles the payment */ + PLGN_ACT_PAY_SIGN_REQ = 0x80000, /**< signs a request */ + PLGN_ACT_LOG_ERROR = 0x100000, /**< report an error */ + PLGN_ACT_NL_PICK = 0x200000, /**< picks the data nodes, plgn_ctx will be a pointer to in3_req_t */ + PLGN_ACT_NL_PICK_FOLLOWUP = 0x400000, /**< called after receiving a response in order to decide whether a update is needed, plgn_ctx will be a pointer to in3_req_t */ + PLGN_ACT_NL_BLACKLIST = 0x800000, /**< blacklist a particular node in the nodelist, plgn_ctx will be a pointer to the node's address. */ + PLGN_ACT_NL_FAILABLE = 0x1000000, /**< handle fail-able request, plgn_ctx will be a pointer to in3_req_t */ + PLGN_ACT_NL_OFFLINE = 0x2000000, /**< mark a particular node in the nodelist as offline, plgn_ctx will be a pointer to in3_nl_offline_ctx_t. */ + PLGN_ACT_CHAIN_CHANGE = 0x4000000, /**< chain id change event, called after setting new chain id */ + PLGN_ACT_GET_DATA = 0x8000000, /**< get access to plugin data as a void ptr */ + PLGN_ACT_ADD_PAYLOAD = 0x10000000, /**< add plugin specific metadata to payload, plgn_ctx will be a sb_t pointer, make sure to begin with a comma */ } in3_plugin_act_t; /** diff --git a/c/include/in3/plugin.h b/c/include/in3/plugin.h index 4ee22f8d8..7adc2b339 100644 --- a/c/include/in3/plugin.h +++ b/c/include/in3/plugin.h @@ -257,7 +257,7 @@ typedef enum { SIGNER_EIP1271 = 2 } in3_signer_type_t; /** - * action context when retrieving the account of a signer. + * action context when retrieving the addresses or accounts of a signer. */ typedef struct sign_account_ctx { struct in3_req* req; /**< the context of the request in order report errors */ @@ -265,6 +265,14 @@ typedef struct sign_account_ctx { int accounts_len; /**< number of accounts */ in3_signer_type_t signer_type; /**< the type of the signer used for this account.*/ } in3_sign_account_ctx_t; +/** + * action context when retrieving the public key of the signer. + */ +typedef struct sign_public_key_ctx { + struct in3_req* req; /**< the context of the request in order report errors */ + uint8_t* account; /**< the account to use for the signature */ + uint8_t public_key[64]; /**< the public key in case the plugin returns IN3_OK */ +} in3_sign_public_key_ctx_t; // ----------- SIGN_PREPARE --------------- @@ -287,6 +295,7 @@ typedef enum { SIGN_EC_RAW = 0, /**< sign the data directly */ SIGN_EC_HASH = 1, /**< hash and sign the data */ SIGN_EC_PREFIX = 2, /**< add Ethereum Signed Message-Proefix, hash and sign the data */ + SIGN_EC_BTC = 3, /**< hashes the data twice with sha256 and signs it */ } d_signature_type_t; /** payload type of the requested signature. It describes how to deserialize the payload. */ diff --git a/c/include/in3/signer.h b/c/include/in3/signer.h index ba19a5313..38f3e015a 100644 --- a/c/include/in3/signer.h +++ b/c/include/in3/signer.h @@ -45,6 +45,7 @@ extern "C" { #endif #include "client.h" +#include "plugin.h" typedef enum { hasher_sha2, @@ -90,6 +91,9 @@ in3_ret_t ec_sign_pk_raw(uint8_t* message, uint8_t* pk, uint8_t* dst); /** hashes the msg by adding the Ethereum Signed Message-Prefix */ void eth_create_prefixed_msg_hash(bytes32_t dst, bytes_t msg); + +/** signs with a pk bases on the type */ +bytes_t sign_with_pk(const bytes32_t pk, const bytes_t data, const d_signature_type_t type); #ifdef __cplusplus } #endif From 0a952dbd9b092922f24960de252bfb99e5425cd5 Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Tue, 12 Oct 2021 14:24:18 +0200 Subject: [PATCH 072/101] fix js-plugins --- wasm/src/in3.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/wasm/src/in3.js b/wasm/src/in3.js index c48a0ea92..fe47b66f4 100644 --- a/wasm/src/in3.js +++ b/wasm/src/in3.js @@ -253,11 +253,11 @@ class IN3 { let action = 0 if (plgn.term) action |= 0x2 if (plgn.getAccounts) action |= 0x20 - if (plgn.handleRPC) action |= 0x100 - if (plgn.verifyRPC) action |= 0x200 - if (plgn.cacheGet) action |= 0x800 - if (plgn.cacheSet) action |= 0x400 - if (plgn.cacheClear) action |= 0x1000 + if (plgn.handleRPC) action |= 0x200 + if (plgn.verifyRPC) action |= 0x400 + if (plgn.cacheGet) action |= 0x1000 + if (plgn.cacheSet) action |= 0x800 + if (plgn.cacheClear) action |= 0x2000 let index = this.plugins.indexOf(plgn) if (index == -1) { index = this.plugins.length From 3b6e828a394668d5f0f350468a6c0eb406fb6f13 Mon Sep 17 00:00:00 2001 From: leonardotc Date: Thu, 21 Oct 2021 11:29:43 +0200 Subject: [PATCH 073/101] Fix transport wait for bindings --- c/src/core/client/execute.c | 1 + 1 file changed, 1 insertion(+) diff --git a/c/src/core/client/execute.c b/c/src/core/client/execute.c index b50c03ef4..a5c8cb8ed 100644 --- a/c/src/core/client/execute.c +++ b/c/src/core/client/execute.c @@ -559,6 +559,7 @@ NONULL in3_http_request_t* in3_create_request(in3_req_t* ctx) { request->urls = _malloc(sizeof(char*)); request->urls[0] = _strdupn(d_get_string_at(params, 1), -1); request->method = method ? method : (*request->payload ? "POST" : "GET"); + request->wait = d_get_int(d_get(ctx->requests[0], K_IN3), K_WAIT); ctx->raw_response = _calloc(sizeof(in3_response_t), 1); ctx->raw_response[0].state = IN3_WAITING; From 33c7aedab4af2294c490a9f78a689a087966ba53 Mon Sep 17 00:00:00 2001 From: leonardotc Date: Fri, 22 Oct 2021 10:40:36 +0200 Subject: [PATCH 074/101] Add in3_rpc_handle_with_json function --- c/src/core/client/plugin.h | 5 +++++ c/src/core/client/request.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/c/src/core/client/plugin.h b/c/src/core/client/plugin.h index 7adc2b339..1d530485c 100644 --- a/c/src/core/client/plugin.h +++ b/c/src/core/client/plugin.h @@ -119,6 +119,11 @@ NONULL in3_ret_t in3_rpc_handle_finish(in3_rpc_handle_ctx_t* hctx); */ NONULL in3_ret_t in3_rpc_handle_with_bytes(in3_rpc_handle_ctx_t* hctx, bytes_t data); +/** + * creates a response with a json token. + */ +NONULL in3_ret_t in3_rpc_handle_with_json(in3_rpc_handle_ctx_t* ctx, d_token_t* result); + /** * creates a response with string. */ diff --git a/c/src/core/client/request.c b/c/src/core/client/request.c index 8b9fe535a..4b478f02f 100644 --- a/c/src/core/client/request.c +++ b/c/src/core/client/request.c @@ -55,6 +55,15 @@ static in3_ret_t in3_plugin_init(in3_req_t* ctx) { return IN3_OK; } +bool in_property_name(char* c) { + for (c++; *c && *c != '"'; c++) { + if (*c == '\\') c++; + } + if (*c) c++; + while (*c && (*c == ' ' || *c < 14)) c++; + return *c == ':'; +} + in3_req_t* req_new_clone(in3_t* client, const char* req_data) { char* data = _strdupn(req_data, -1); in3_req_t* r = req_new(client, data); @@ -326,6 +335,26 @@ in3_ret_t in3_rpc_handle_with_string(in3_rpc_handle_ctx_t* hctx, char* data) { return in3_rpc_handle_finish(hctx); } +in3_ret_t in3_rpc_handle_with_json(in3_rpc_handle_ctx_t* ctx, d_token_t* result) { + if (!result) return req_set_error(ctx->req, "No result", IN3_ERPC); + sb_t* sb = in3_rpc_handle_start(ctx); + + // As the API might return an empty string as a response, + // we at least convert it into an empty object + if ((d_type(result) == T_STRING || d_type(result) == T_BYTES) && d_len(result) == 0) { + sb_add_chars(sb, "{}"); + } + else { + sb_add_json(sb, "", result); + } + + // now convert all kebab-case to pascal case + for (char* c = sb->data; *c; c++) { + if (*c == '-' && in_property_name(c)) *c = '_'; + } + return in3_rpc_handle_finish(ctx); +} + in3_ret_t in3_rpc_handle_with_int(in3_rpc_handle_ctx_t* hctx, uint64_t value) { uint8_t val[8]; long_to_bytes(value, val); From 38655561d983573c29cec9f2ce04f7f32c35cc07 Mon Sep 17 00:00:00 2001 From: leonardotc Date: Mon, 25 Oct 2021 12:54:00 +0200 Subject: [PATCH 075/101] Fix python build --- python/ci.yml | 6 +++--- python/requirements.txt | 2 +- scripts/test_python.sh | 10 +++++++++- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/python/ci.yml b/python/ci.yml index f7edfa699..dabf6bbba 100644 --- a/python/ci.yml +++ b/python/ci.yml @@ -33,7 +33,7 @@ - source venv/bin/activate python: - image: python + image: "python:3.9" stage: bindings needs: - mac_os @@ -63,7 +63,7 @@ python: python_arm: allow_failure: true - image: python + image: "python:3.9" extends: .cache_setup_with_only_python needs: - python @@ -136,7 +136,7 @@ python_linux: coverage: '/TOTAL\s+\d+\s+\d+\s+([0-9.]+%)/' needs: - python - image: python + image: "python:3.9" stage: python before_script: - *cache_scipt_before diff --git a/python/requirements.txt b/python/requirements.txt index 9a89acdb5..7c3791783 100644 --- a/python/requirements.txt +++ b/python/requirements.txt @@ -45,7 +45,7 @@ snowballstemmer==2.0.0 tornado==6.0.4 tqdm==4.46.0 twine==3.1.1 -typed-ast==1.4.1 +typed-ast==1.4.3 urllib3==1.25.8 wcwidth==0.1.9 webencodings==0.5.1 diff --git a/scripts/test_python.sh b/scripts/test_python.sh index 49113b978..441701efc 100755 --- a/scripts/test_python.sh +++ b/scripts/test_python.sh @@ -1,10 +1,18 @@ #!/bin/sh +MAC_FILE=../build/lib/libin3.dylib +LINUX_FILE=../build/lib/libin3.so + CWD=$PWD cd $(dirname $0)/../build make cd ../python mkdir -p in3/libin3/shared -cp ../build/lib/libin3.dylib in3/libin3/shared/libin3.x64.dylib +if test -f "$LINUX_FILE"; then + cp "$LINUX_FILE" in3/libin3/shared/libin3.x64.so +else + cp "$MAC_FILE" in3/libin3/shared/libin3.x64.dylib +fi + pip3 install -r requirements.txt coverage run -m pytest --pylama --junitxml=report.xml cd $CWD From ecbe5e2dd39613060836adc2c2391f5d99d94e56 Mon Sep 17 00:00:00 2001 From: leonardotc Date: Wed, 27 Oct 2021 11:57:36 +0200 Subject: [PATCH 076/101] Update ipfs dependency --- c/src/third-party/nanopb/pb.h | 815 ++++++++++++++++++---------------- 1 file changed, 428 insertions(+), 387 deletions(-) diff --git a/c/src/third-party/nanopb/pb.h b/c/src/third-party/nanopb/pb.h index 283570467..e1056cfbd 100755 --- a/c/src/third-party/nanopb/pb.h +++ b/c/src/third-party/nanopb/pb.h @@ -1,26 +1,3 @@ -/******************************************************************************* - * Copyright (c) 2011 Petteri Aimonen - * - * This software is provided 'as-is', without any express or - * implied warranty. In no event will the authors be held liable - * for any damages arising from the use of this software. - * - * Permission is granted to anyone to use this software for any - * purpose, including commercial applications, and to alter it and - * redistribute it freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you - * must not claim that you wrote the original software. If you use - * this software in a product, an acknowledgment in the product - * documentation would be appreciated but is not required. - * - * 2. Altered source versions must be plainly marked as such, and - * must not be misrepresented as being the original software. - * - * 3. This notice may not be removed or altered from any source - * distribution. - *******************************************************************************/ - /* Common parts of the nanopb library. Most of these are quite low-level * stuff. For the high-level interface, see pb_encode.h and pb_decode.h. */ @@ -37,7 +14,8 @@ /* #define PB_ENABLE_MALLOC 1 */ /* Define this if your CPU / compiler combination does not support - * unaligned memory access to packed structures. */ + * unaligned memory access to packed structures. Note that packed + * structures are only used when requested in .proto options. */ /* #define PB_NO_PACKED_STRUCTS 1 */ /* Increase the number of required fields that are tracked. @@ -57,12 +35,6 @@ or to save some code space. */ /* #define PB_WITHOUT_64BIT 1 */ -/* Set the fieldinfo width for all messages using automatic width - * selection. Valid values are 2, 4 and 8. Usually even if you need - * to change the width manually for some reason, it is preferrable - * to do so through the descriptorsize option in .options file. */ -/* #define PB_FIELDINFO_WIDTH 4 */ - /* Don't encode scalar arrays as packed. This is only to be used when * the decoder on the receiving side cannot process packed scalar arrays. * Such example is older protobuf.js. */ @@ -76,14 +48,19 @@ * the string processing slightly and slightly increases code size. */ /* #define PB_VALIDATE_UTF8 1 */ +/* This can be defined if the platform is little-endian and has 8-bit bytes. + * Normally it is automatically detected based on __BYTE_ORDER__ macro. */ +/* #define PB_LITTLE_ENDIAN_8BIT 1 */ + /****************************************************************** * You usually don't need to change anything below this line. * * Feel free to look around and use the defined macros, though. * ******************************************************************/ + /* Version of the nanopb library. Just in case you want to check it in * your own program. */ -#define NANOPB_VERSION nanopb - 0.4.0 +#define NANOPB_VERSION "nanopb-0.4.6-dev" /* Include all the system headers needed by nanopb. You will need the * definitions of the following: @@ -99,11 +76,11 @@ #ifdef PB_SYSTEM_HEADER #include PB_SYSTEM_HEADER #else -#include -#include -#include #include +#include +#include #include +#include #ifdef PB_ENABLE_MALLOC #include @@ -118,35 +95,47 @@ extern "C" { * This just reduces memory requirements, but is not required. */ #if defined(PB_NO_PACKED_STRUCTS) -/* Disable struct packing */ -#define PB_PACKED_STRUCT_START -#define PB_PACKED_STRUCT_END -#define pb_packed + /* Disable struct packing */ +# define PB_PACKED_STRUCT_START +# define PB_PACKED_STRUCT_END +# define pb_packed #elif defined(__GNUC__) || defined(__clang__) -/* For GCC and clang */ -#define PB_PACKED_STRUCT_START -#define PB_PACKED_STRUCT_END -#define pb_packed __attribute__((packed)) + /* For GCC and clang */ +# define PB_PACKED_STRUCT_START +# define PB_PACKED_STRUCT_END +# define pb_packed __attribute__((packed)) #elif defined(__ICCARM__) || defined(__CC_ARM) -/* For IAR ARM and Keil MDK-ARM compilers */ -#define PB_PACKED_STRUCT_START _Pragma("pack(push, 1)") -#define PB_PACKED_STRUCT_END _Pragma("pack(pop)") -#define pb_packed + /* For IAR ARM and Keil MDK-ARM compilers */ +# define PB_PACKED_STRUCT_START _Pragma("pack(push, 1)") +# define PB_PACKED_STRUCT_END _Pragma("pack(pop)") +# define pb_packed #elif defined(_MSC_VER) && (_MSC_VER >= 1500) -/* For Microsoft Visual C++ */ -#define PB_PACKED_STRUCT_START __pragma(pack(push, 1)) -#define PB_PACKED_STRUCT_END __pragma(pack(pop)) -#define pb_packed + /* For Microsoft Visual C++ */ +# define PB_PACKED_STRUCT_START __pragma(pack(push, 1)) +# define PB_PACKED_STRUCT_END __pragma(pack(pop)) +# define pb_packed #else -/* Unknown compiler */ -#define PB_PACKED_STRUCT_START -#define PB_PACKED_STRUCT_END -#define pb_packed + /* Unknown compiler */ +# define PB_PACKED_STRUCT_START +# define PB_PACKED_STRUCT_END +# define pb_packed +#endif + +/* Detect endianess */ +#ifndef PB_LITTLE_ENDIAN_8BIT +#if ((defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN) || \ + (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || \ + defined(__LITTLE_ENDIAN__) || defined(__ARMEL__) || \ + defined(__THUMBEL__) || defined(__AARCH64EL__) || defined(_MIPSEL) || \ + defined(_M_IX86) || defined(_M_X64) || defined(_M_ARM)) \ + && CHAR_BIT == 8 +#define PB_LITTLE_ENDIAN_8BIT 1 +#endif #endif /* Handly macro for suppressing unreferenced-parameter compiler warnings. */ #ifndef PB_UNUSED -#define PB_UNUSED(x) (void) (x) +#define PB_UNUSED(x) (void)(x) #endif /* Harvard-architecture processors may need special attributes for storing @@ -154,11 +143,11 @@ extern "C" { #ifndef PB_PROGMEM #ifdef __AVR__ #include -#define PB_PROGMEM PROGMEM -#define PB_PROGMEM_READU32(x) pgm_read_dword(&x) +#define PB_PROGMEM PROGMEM +#define PB_PROGMEM_READU32(x) pgm_read_dword(&x) #else #define PB_PROGMEM -#define PB_PROGMEM_READU32(x) (x) +#define PB_PROGMEM_READU32(x) (x) #endif #endif @@ -172,20 +161,23 @@ extern "C" { * in the place where the PB_STATIC_ASSERT macro was called. */ #ifndef PB_NO_STATIC_ASSERT -#ifndef PB_STATIC_ASSERT -#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L -/* C11 standard _Static_assert mechanism */ -#define PB_STATIC_ASSERT(COND, MSG) _Static_assert(COND, #MSG); -#else -/* Classic negative-size-array static assert mechanism */ -#define PB_STATIC_ASSERT(COND, MSG) typedef char PB_STATIC_ASSERT_MSG(MSG, __LINE__, __COUNTER__)[(COND) ? 1 : -1]; -#define PB_STATIC_ASSERT_MSG(MSG, LINE, COUNTER) PB_STATIC_ASSERT_MSG_(MSG, LINE, COUNTER) -#define PB_STATIC_ASSERT_MSG_(MSG, LINE, COUNTER) pb_static_assertion_##MSG##_##LINE##_##COUNTER -#endif -#endif +# ifndef PB_STATIC_ASSERT +# if defined(__ICCARM__) + /* IAR has static_assert keyword but no _Static_assert */ +# define PB_STATIC_ASSERT(COND,MSG) static_assert(COND,#MSG); +# elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L + /* C11 standard _Static_assert mechanism */ +# define PB_STATIC_ASSERT(COND,MSG) _Static_assert(COND,#MSG); +# else + /* Classic negative-size-array static assert mechanism */ +# define PB_STATIC_ASSERT(COND,MSG) typedef char PB_STATIC_ASSERT_MSG(MSG, __LINE__, __COUNTER__)[(COND)?1:-1]; +# define PB_STATIC_ASSERT_MSG(MSG, LINE, COUNTER) PB_STATIC_ASSERT_MSG_(MSG, LINE, COUNTER) +# define PB_STATIC_ASSERT_MSG_(MSG, LINE, COUNTER) pb_static_assertion_##MSG##_##LINE##_##COUNTER +# endif +# endif #else -/* Static asserts disabled by PB_NO_STATIC_ASSERT */ -#define PB_STATIC_ASSERT(COND, MSG) + /* Static asserts disabled by PB_NO_STATIC_ASSERT */ +# define PB_STATIC_ASSERT(COND,MSG) #endif /* Number of required fields to keep track of. */ @@ -214,8 +206,8 @@ typedef uint_least8_t pb_type_t; /**** Field data types ****/ /* Numeric types */ -#define PB_LTYPE_BOOL 0x00U /* bool */ -#define PB_LTYPE_VARINT 0x01U /* int32, int64, enum, bool */ +#define PB_LTYPE_BOOL 0x00U /* bool */ +#define PB_LTYPE_VARINT 0x01U /* int32, int64, enum, bool */ #define PB_LTYPE_UVARINT 0x02U /* uint32, uint64 */ #define PB_LTYPE_SVARINT 0x03U /* sint32, sint64 */ #define PB_LTYPE_FIXED32 0x04U /* fixed32, sfixed32, float */ @@ -262,19 +254,19 @@ typedef uint_least8_t pb_type_t; #define PB_HTYPE_SINGULAR 0x10U #define PB_HTYPE_REPEATED 0x20U #define PB_HTYPE_FIXARRAY 0x20U -#define PB_HTYPE_ONEOF 0x30U -#define PB_HTYPE_MASK 0x30U +#define PB_HTYPE_ONEOF 0x30U +#define PB_HTYPE_MASK 0x30U /**** Field allocation types ****/ -#define PB_ATYPE_STATIC 0x00U -#define PB_ATYPE_POINTER 0x80U +#define PB_ATYPE_STATIC 0x00U +#define PB_ATYPE_POINTER 0x80U #define PB_ATYPE_CALLBACK 0x40U -#define PB_ATYPE_MASK 0xC0U +#define PB_ATYPE_MASK 0xC0U -#define PB_ATYPE(x) ((x) &PB_ATYPE_MASK) -#define PB_HTYPE(x) ((x) &PB_HTYPE_MASK) -#define PB_LTYPE(x) ((x) &PB_LTYPE_MASK) +#define PB_ATYPE(x) ((x) & PB_ATYPE_MASK) +#define PB_HTYPE(x) ((x) & PB_HTYPE_MASK) +#define PB_LTYPE(x) ((x) & PB_LTYPE_MASK) #define PB_LTYPE_IS_SUBMSG(x) (PB_LTYPE(x) == PB_LTYPE_SUBMESSAGE || \ PB_LTYPE(x) == PB_LTYPE_SUBMSG_W_CB) @@ -282,13 +274,13 @@ typedef uint_least8_t pb_type_t; * and array counts. */ #if defined(PB_FIELD_32BIT) -typedef uint32_t pb_size_t; -typedef int32_t pb_ssize_t; + typedef uint32_t pb_size_t; + typedef int32_t pb_ssize_t; #else -typedef uint_least16_t pb_size_t; -typedef int_least16_t pb_ssize_t; + typedef uint_least16_t pb_size_t; + typedef int_least16_t pb_ssize_t; #endif -#define PB_SIZE_MAX ((pb_size_t) -1) +#define PB_SIZE_MAX ((pb_size_t)-1) /* Data type for storing encoded data and other byte streams. * This typedef exists to support platforms where uint8_t does not exist. @@ -297,45 +289,46 @@ typedef int_least16_t pb_ssize_t; typedef uint_least8_t pb_byte_t; /* Forward declaration of struct types */ -typedef struct pb_istream_s pb_istream_t; -typedef struct pb_ostream_s pb_ostream_t; +typedef struct pb_istream_s pb_istream_t; +typedef struct pb_ostream_s pb_ostream_t; typedef struct pb_field_iter_s pb_field_iter_t; /* This structure is used in auto-generated constants * to specify struct fields. */ -PB_PACKED_STRUCT_START typedef struct pb_msgdesc_s pb_msgdesc_t; struct pb_msgdesc_s { - pb_size_t field_count; - const uint32_t* field_info; - const pb_msgdesc_t* const* submsg_info; - const pb_byte_t* default_value; + const uint32_t *field_info; + const pb_msgdesc_t * const * submsg_info; + const pb_byte_t *default_value; - bool (*field_callback)(pb_istream_t* istream, pb_ostream_t* ostream, const pb_field_iter_t* field); -} pb_packed; -PB_PACKED_STRUCT_END + bool (*field_callback)(pb_istream_t *istream, pb_ostream_t *ostream, const pb_field_iter_t *field); + + pb_size_t field_count; + pb_size_t required_field_count; + pb_size_t largest_tag; +}; /* Iterator for message descriptor */ struct pb_field_iter_s { - const pb_msgdesc_t* descriptor; /* Pointer to message descriptor constant */ - void* message; /* Pointer to start of the structure */ + const pb_msgdesc_t *descriptor; /* Pointer to message descriptor constant */ + void *message; /* Pointer to start of the structure */ - pb_size_t index; /* Index of the field */ - pb_size_t field_info_index; /* Index to descriptor->field_info array */ - pb_size_t required_field_index; /* Index that counts only the required fields */ - pb_size_t submessage_index; /* Index that counts only submessages */ + pb_size_t index; /* Index of the field */ + pb_size_t field_info_index; /* Index to descriptor->field_info array */ + pb_size_t required_field_index; /* Index that counts only the required fields */ + pb_size_t submessage_index; /* Index that counts only submessages */ - pb_size_t tag; /* Tag of current field */ - pb_size_t data_size; /* sizeof() of a single item */ - pb_size_t array_size; /* Number of array entries */ - pb_type_t type; /* Type of current field */ + pb_size_t tag; /* Tag of current field */ + pb_size_t data_size; /* sizeof() of a single item */ + pb_size_t array_size; /* Number of array entries */ + pb_type_t type; /* Type of current field */ - void* pField; /* Pointer to current field in struct */ - void* pData; /* Pointer to current data contents. Different than pField for arrays and pointers. */ - void* pSize; /* Pointer to count/has field */ + void *pField; /* Pointer to current field in struct */ + void *pData; /* Pointer to current data contents. Different than pField for arrays and pointers. */ + void *pSize; /* Pointer to count/has field */ - const pb_msgdesc_t* submsg_desc; /* For submessage fields, pointer to field descriptor for the submessage. */ + const pb_msgdesc_t *submsg_desc; /* For submessage fields, pointer to field descriptor for the submessage. */ }; /* For compatibility with legacy code */ @@ -356,16 +349,12 @@ PB_STATIC_ASSERT(sizeof(uint64_t) == 2 * sizeof(uint32_t), UINT64_T_WRONG_SIZE) * It has the number of bytes in the beginning, and after that an array. * Note that actual structs used will have a different length of bytes array. */ -#define PB_BYTES_ARRAY_T(n) \ - struct { \ - pb_size_t size; \ - pb_byte_t bytes[n]; \ - } -#define PB_BYTES_ARRAY_T_ALLOCSIZE(n) ((size_t) n + offsetof(pb_bytes_array_t, bytes)) +#define PB_BYTES_ARRAY_T(n) struct { pb_size_t size; pb_byte_t bytes[n]; } +#define PB_BYTES_ARRAY_T_ALLOCSIZE(n) ((size_t)n + offsetof(pb_bytes_array_t, bytes)) struct pb_bytes_array_s { - pb_size_t size; - pb_byte_t bytes[1]; + pb_size_t size; + pb_byte_t bytes[1]; }; typedef struct pb_bytes_array_s pb_bytes_array_t; @@ -389,26 +378,27 @@ typedef struct pb_bytes_array_s pb_bytes_array_t; */ typedef struct pb_callback_s pb_callback_t; struct pb_callback_s { - /* Callback functions receive a pointer to the arg field. + /* Callback functions receive a pointer to the arg field. * You can access the value of the field as *arg, and modify it if needed. */ - union { - bool (*decode)(pb_istream_t* stream, const pb_field_t* field, void** arg); - bool (*encode)(pb_ostream_t* stream, const pb_field_t* field, void* const* arg); - } funcs; + union { + bool (*decode)(pb_istream_t *stream, const pb_field_t *field, void **arg); + bool (*encode)(pb_ostream_t *stream, const pb_field_t *field, void * const *arg); + } funcs; - /* Free arg for use by callback */ - void* arg; + /* Free arg for use by callback */ + void *arg; }; -extern bool pb_default_field_callback(pb_istream_t* istream, pb_ostream_t* ostream, const pb_field_t* field); +extern bool pb_default_field_callback(pb_istream_t *istream, pb_ostream_t *ostream, const pb_field_t *field); /* Wire types. Library user needs these only in encoder callbacks. */ typedef enum { - PB_WT_VARINT = 0, - PB_WT_64BIT = 1, - PB_WT_STRING = 2, - PB_WT_32BIT = 5 + PB_WT_VARINT = 0, + PB_WT_64BIT = 1, + PB_WT_STRING = 2, + PB_WT_32BIT = 5, + PB_WT_PACKED = 255 /* PB_WT_PACKED is internal marker for packed arrays. */ } pb_wire_type_t; /* Structure for defining the handling of unknown/extension fields. @@ -418,60 +408,59 @@ typedef enum { * pb_extension_type_t with your own callback. */ typedef struct pb_extension_type_s pb_extension_type_t; -typedef struct pb_extension_s pb_extension_t; +typedef struct pb_extension_s pb_extension_t; struct pb_extension_type_s { - /* Called for each unknown field in the message. + /* Called for each unknown field in the message. * If you handle the field, read off all of its data and return true. * If you do not handle the field, do not read anything and return true. * If you run into an error, return false. * Set to NULL for default handler. */ - bool (*decode)(pb_istream_t* stream, pb_extension_t* extension, - uint32_t tag, pb_wire_type_t wire_type); + bool (*decode)(pb_istream_t *stream, pb_extension_t *extension, + uint32_t tag, pb_wire_type_t wire_type); - /* Called once after all regular fields have been encoded. + /* Called once after all regular fields have been encoded. * If you have something to write, do so and return true. * If you do not have anything to write, just return true. * If you run into an error, return false. * Set to NULL for default handler. */ - bool (*encode)(pb_ostream_t* stream, const pb_extension_t* extension); + bool (*encode)(pb_ostream_t *stream, const pb_extension_t *extension); - /* Free field for use by the callback. */ - const void* arg; + /* Free field for use by the callback. */ + const void *arg; }; struct pb_extension_s { - /* Type describing the extension field. Usually you'll initialize + /* Type describing the extension field. Usually you'll initialize * this to a pointer to the automatically generated structure. */ - const pb_extension_type_t* type; + const pb_extension_type_t *type; - /* Destination for the decoded data. This must match the datatype + /* Destination for the decoded data. This must match the datatype * of the extension field. */ - void* dest; + void *dest; - /* Pointer to the next extension handler, or NULL. + /* Pointer to the next extension handler, or NULL. * If this extension does not match a field, the next handler is * automatically called. */ - pb_extension_t* next; + pb_extension_t *next; - /* The decoder sets this to true if the extension was found. + /* The decoder sets this to true if the extension was found. * Ignored for encoding. */ - bool found; + bool found; }; -#define pb_extension_init_zero \ - { NULL, NULL, NULL, false } +#define pb_extension_init_zero {NULL,NULL,NULL,false} /* Memory allocation functions to use. You can define pb_realloc and * pb_free to custom functions if you want. */ #ifdef PB_ENABLE_MALLOC -#ifndef pb_realloc -#define pb_realloc(ptr, size) realloc(ptr, size) -#endif -#ifndef pb_free -#define pb_free(ptr) free(ptr) -#endif +# ifndef pb_realloc +# define pb_realloc(ptr, size) realloc(ptr, size) +# endif +# ifndef pb_free +# define pb_free(ptr) free(ptr) +# endif #endif /* This is used to inform about need to regenerate .pb.h/.pb.c files. */ @@ -479,190 +468,243 @@ struct pb_extension_s { /* These macros are used to declare pb_field_t's in the constant array. */ /* Size of a structure member, in bytes. */ -#define pb_membersize(st, m) (sizeof((st*) 0)->m) +#define pb_membersize(st, m) (sizeof ((st*)0)->m) /* Number of entries in an array. */ #define pb_arraysize(st, m) (pb_membersize(st, m) / pb_membersize(st, m[0])) /* Delta from start of one member to the start of another member. */ -#define pb_delta(st, m1, m2) ((int) offsetof(st, m1) - (int) offsetof(st, m2)) +#define pb_delta(st, m1, m2) ((int)offsetof(st, m1) - (int)offsetof(st, m2)) /* Force expansion of macro value */ #define PB_EXPAND(x) x /* Binding of a message field set into a specific structure */ -#define PB_BIND(msgname, structname, width) \ - const uint32_t structname##_field_info[] PB_PROGMEM = \ - { \ - msgname##_FIELDLIST(PB_GEN_FIELD_INFO_##width, structname) 0}; \ - const pb_msgdesc_t* const structname##_submsg_info[] = \ - { \ - msgname##_FIELDLIST(PB_GEN_SUBMSG_INFO, structname) \ - NULL}; \ - const pb_msgdesc_t structname##_msg = \ - { \ - 0 msgname##_FIELDLIST(PB_GEN_FIELD_COUNT, structname), \ - structname##_field_info, \ - structname##_submsg_info, \ - msgname##_DEFAULT, \ - msgname##_CALLBACK, \ - }; \ - msgname##_FIELDLIST(PB_GEN_FIELD_INFO_ASSERT_##width, structname) +#define PB_BIND(msgname, structname, width) \ + const uint32_t structname ## _field_info[] PB_PROGMEM = \ + { \ + msgname ## _FIELDLIST(PB_GEN_FIELD_INFO_ ## width, structname) \ + 0 \ + }; \ + const pb_msgdesc_t* const structname ## _submsg_info[] = \ + { \ + msgname ## _FIELDLIST(PB_GEN_SUBMSG_INFO, structname) \ + NULL \ + }; \ + const pb_msgdesc_t structname ## _msg = \ + { \ + structname ## _field_info, \ + structname ## _submsg_info, \ + msgname ## _DEFAULT, \ + msgname ## _CALLBACK, \ + 0 msgname ## _FIELDLIST(PB_GEN_FIELD_COUNT, structname), \ + 0 msgname ## _FIELDLIST(PB_GEN_REQ_FIELD_COUNT, structname), \ + 0 msgname ## _FIELDLIST(PB_GEN_LARGEST_TAG, structname), \ + }; \ + msgname ## _FIELDLIST(PB_GEN_FIELD_INFO_ASSERT_ ## width, structname) #define PB_GEN_FIELD_COUNT(structname, atype, htype, ltype, fieldname, tag) +1 +#define PB_GEN_REQ_FIELD_COUNT(structname, atype, htype, ltype, fieldname, tag) \ + + (PB_HTYPE_ ## htype == PB_HTYPE_REQUIRED) +#define PB_GEN_LARGEST_TAG(structname, atype, htype, ltype, fieldname, tag) \ + * 0 + tag +/* X-macro for generating the entries in struct_field_info[] array. */ #define PB_GEN_FIELD_INFO_1(structname, atype, htype, ltype, fieldname, tag) \ - PB_GEN_FIELD_INFO(1, structname, atype, htype, ltype, fieldname, tag) + PB_FIELDINFO_1(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ + PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) #define PB_GEN_FIELD_INFO_2(structname, atype, htype, ltype, fieldname, tag) \ - PB_GEN_FIELD_INFO(2, structname, atype, htype, ltype, fieldname, tag) + PB_FIELDINFO_2(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ + PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) #define PB_GEN_FIELD_INFO_4(structname, atype, htype, ltype, fieldname, tag) \ - PB_GEN_FIELD_INFO(4, structname, atype, htype, ltype, fieldname, tag) + PB_FIELDINFO_4(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ + PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) #define PB_GEN_FIELD_INFO_8(structname, atype, htype, ltype, fieldname, tag) \ - PB_GEN_FIELD_INFO(8, structname, atype, htype, ltype, fieldname, tag) + PB_FIELDINFO_8(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ + PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) #define PB_GEN_FIELD_INFO_AUTO(structname, atype, htype, ltype, fieldname, tag) \ - PB_GEN_FIELD_INFO_AUTO2(PB_FIELDINFO_WIDTH_AUTO(atype, htype, ltype), structname, atype, htype, ltype, fieldname, tag) - -#define PB_GEN_FIELD_INFO_AUTO2(width, structname, atype, htype, ltype, fieldname, tag) \ - PB_GEN_FIELD_INFO(width, structname, atype, htype, ltype, fieldname, tag) - -#define PB_GEN_FIELD_INFO(width, structname, atype, htype, ltype, fieldname, tag) \ - PB_FIELDINFO_##width(tag, PB_ATYPE_##atype | PB_HTYPE_##htype | PB_LTYPE_MAP_##ltype, \ - PB_DATA_OFFSET_##atype(htype, structname, fieldname), \ - PB_DATA_SIZE_##atype(htype, structname, fieldname), \ - PB_SIZE_OFFSET_##atype(htype, structname, fieldname), \ - PB_ARRAY_SIZE_##atype(htype, structname, fieldname)) - + PB_FIELDINFO_AUTO2(PB_FIELDINFO_WIDTH_AUTO(_PB_ATYPE_ ## atype, _PB_HTYPE_ ## htype, _PB_LTYPE_ ## ltype), \ + tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ + PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) + +#define PB_FIELDINFO_AUTO2(width, tag, type, data_offset, data_size, size_offset, array_size) \ + PB_FIELDINFO_AUTO3(width, tag, type, data_offset, data_size, size_offset, array_size) + +#define PB_FIELDINFO_AUTO3(width, tag, type, data_offset, data_size, size_offset, array_size) \ + PB_FIELDINFO_ ## width(tag, type, data_offset, data_size, size_offset, array_size) + +/* X-macro for generating asserts that entries fit in struct_field_info[] array. + * The structure of macros here must match the structure above in PB_GEN_FIELD_INFO_x(), + * but it is not easily reused because of how macro substitutions work. */ #define PB_GEN_FIELD_INFO_ASSERT_1(structname, atype, htype, ltype, fieldname, tag) \ - PB_GEN_FIELD_INFO_ASSERT(1, structname, atype, htype, ltype, fieldname, tag) + PB_FIELDINFO_ASSERT_1(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ + PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) #define PB_GEN_FIELD_INFO_ASSERT_2(structname, atype, htype, ltype, fieldname, tag) \ - PB_GEN_FIELD_INFO_ASSERT(2, structname, atype, htype, ltype, fieldname, tag) + PB_FIELDINFO_ASSERT_2(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ + PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) #define PB_GEN_FIELD_INFO_ASSERT_4(structname, atype, htype, ltype, fieldname, tag) \ - PB_GEN_FIELD_INFO_ASSERT(4, structname, atype, htype, ltype, fieldname, tag) + PB_FIELDINFO_ASSERT_4(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ + PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) #define PB_GEN_FIELD_INFO_ASSERT_8(structname, atype, htype, ltype, fieldname, tag) \ - PB_GEN_FIELD_INFO_ASSERT(8, structname, atype, htype, ltype, fieldname, tag) + PB_FIELDINFO_ASSERT_8(tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ + PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) #define PB_GEN_FIELD_INFO_ASSERT_AUTO(structname, atype, htype, ltype, fieldname, tag) \ - PB_GEN_FIELD_INFO_ASSERT_AUTO2(PB_FIELDINFO_WIDTH_AUTO(atype, htype, ltype), structname, atype, htype, ltype, fieldname, tag) - -#define PB_GEN_FIELD_INFO_ASSERT_AUTO2(width, structname, atype, htype, ltype, fieldname, tag) \ - PB_GEN_FIELD_INFO_ASSERT(width, structname, atype, htype, ltype, fieldname, tag) - -#define PB_GEN_FIELD_INFO_ASSERT(width, structname, atype, htype, ltype, fieldname, tag) \ - PB_FIELDINFO_ASSERT_##width(tag, PB_ATYPE_##atype | PB_HTYPE_##htype | PB_LTYPE_MAP_##ltype, \ - PB_DATA_OFFSET_##atype(htype, structname, fieldname), \ - PB_DATA_SIZE_##atype(htype, structname, fieldname), \ - PB_SIZE_OFFSET_##atype(htype, structname, fieldname), \ - PB_ARRAY_SIZE_##atype(htype, structname, fieldname)) - -#define PB_DATA_OFFSET_STATIC(htype, structname, fieldname) PB_DATA_OFFSET_##htype(structname, fieldname) -#define PB_DATA_OFFSET_POINTER(htype, structname, fieldname) PB_DATA_OFFSET_##htype(structname, fieldname) -#define PB_DATA_OFFSET_CALLBACK(htype, structname, fieldname) PB_DATA_OFFSET_##htype(structname, fieldname) -#define PB_DATA_OFFSET_REQUIRED(structname, fieldname) offsetof(structname, fieldname) -#define PB_DATA_OFFSET_SINGULAR(structname, fieldname) offsetof(structname, fieldname) -#define PB_DATA_OFFSET_ONEOF(structname, fieldname) offsetof(structname, PB_ONEOF_NAME(FULL, fieldname)) -#define PB_DATA_OFFSET_OPTIONAL(structname, fieldname) offsetof(structname, fieldname) -#define PB_DATA_OFFSET_REPEATED(structname, fieldname) offsetof(structname, fieldname) -#define PB_DATA_OFFSET_FIXARRAY(structname, fieldname) offsetof(structname, fieldname) - -#define PB_SIZE_OFFSET_STATIC(htype, structname, fieldname) PB_SIZE_OFFSET_##htype(structname, fieldname) -#define PB_SIZE_OFFSET_POINTER(htype, structname, fieldname) PB_SIZE_OFFSET_PTR_##htype(structname, fieldname) -#define PB_SIZE_OFFSET_CALLBACK(htype, structname, fieldname) PB_SIZE_OFFSET_CB_##htype(structname, fieldname) -#define PB_SIZE_OFFSET_REQUIRED(structname, fieldname) 0 -#define PB_SIZE_OFFSET_SINGULAR(structname, fieldname) 0 -#define PB_SIZE_OFFSET_ONEOF(structname, fieldname) PB_SIZE_OFFSET_ONEOF2(structname, PB_ONEOF_NAME(FULL, fieldname), PB_ONEOF_NAME(UNION, fieldname)) -#define PB_SIZE_OFFSET_ONEOF2(structname, fullname, unionname) PB_SIZE_OFFSET_ONEOF3(structname, fullname, unionname) -#define PB_SIZE_OFFSET_ONEOF3(structname, fullname, unionname) pb_delta(structname, fullname, which_##unionname) -#define PB_SIZE_OFFSET_OPTIONAL(structname, fieldname) pb_delta(structname, fieldname, has_##fieldname) -#define PB_SIZE_OFFSET_REPEATED(structname, fieldname) pb_delta(structname, fieldname, fieldname##_count) -#define PB_SIZE_OFFSET_FIXARRAY(structname, fieldname) 0 -#define PB_SIZE_OFFSET_PTR_REQUIRED(structname, fieldname) 0 -#define PB_SIZE_OFFSET_PTR_SINGULAR(structname, fieldname) 0 -#define PB_SIZE_OFFSET_PTR_ONEOF(structname, fieldname) PB_SIZE_OFFSET_ONEOF(structname, fieldname) -#define PB_SIZE_OFFSET_PTR_OPTIONAL(structname, fieldname) 0 -#define PB_SIZE_OFFSET_PTR_REPEATED(structname, fieldname) PB_SIZE_OFFSET_REPEATED(structname, fieldname) -#define PB_SIZE_OFFSET_PTR_FIXARRAY(structname, fieldname) 0 -#define PB_SIZE_OFFSET_CB_REQUIRED(structname, fieldname) 0 -#define PB_SIZE_OFFSET_CB_SINGULAR(structname, fieldname) 0 -#define PB_SIZE_OFFSET_CB_ONEOF(structname, fieldname) PB_SIZE_OFFSET_ONEOF(structname, fieldname) -#define PB_SIZE_OFFSET_CB_OPTIONAL(structname, fieldname) 0 -#define PB_SIZE_OFFSET_CB_REPEATED(structname, fieldname) 0 -#define PB_SIZE_OFFSET_CB_FIXARRAY(structname, fieldname) 0 - -#define PB_ARRAY_SIZE_STATIC(htype, structname, fieldname) PB_ARRAY_SIZE_##htype(structname, fieldname) -#define PB_ARRAY_SIZE_POINTER(htype, structname, fieldname) 1 + PB_FIELDINFO_ASSERT_AUTO2(PB_FIELDINFO_WIDTH_AUTO(_PB_ATYPE_ ## atype, _PB_HTYPE_ ## htype, _PB_LTYPE_ ## ltype), \ + tag, PB_ATYPE_ ## atype | PB_HTYPE_ ## htype | PB_LTYPE_MAP_ ## ltype, \ + PB_DATA_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_DATA_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_SIZE_OFFSET_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname), \ + PB_ARRAY_SIZE_ ## atype(_PB_HTYPE_ ## htype, structname, fieldname)) + +#define PB_FIELDINFO_ASSERT_AUTO2(width, tag, type, data_offset, data_size, size_offset, array_size) \ + PB_FIELDINFO_ASSERT_AUTO3(width, tag, type, data_offset, data_size, size_offset, array_size) + +#define PB_FIELDINFO_ASSERT_AUTO3(width, tag, type, data_offset, data_size, size_offset, array_size) \ + PB_FIELDINFO_ASSERT_ ## width(tag, type, data_offset, data_size, size_offset, array_size) + +#define PB_DATA_OFFSET_STATIC(htype, structname, fieldname) PB_DO ## htype(structname, fieldname) +#define PB_DATA_OFFSET_POINTER(htype, structname, fieldname) PB_DO ## htype(structname, fieldname) +#define PB_DATA_OFFSET_CALLBACK(htype, structname, fieldname) PB_DO ## htype(structname, fieldname) +#define PB_DO_PB_HTYPE_REQUIRED(structname, fieldname) offsetof(structname, fieldname) +#define PB_DO_PB_HTYPE_SINGULAR(structname, fieldname) offsetof(structname, fieldname) +#define PB_DO_PB_HTYPE_ONEOF(structname, fieldname) offsetof(structname, PB_ONEOF_NAME(FULL, fieldname)) +#define PB_DO_PB_HTYPE_OPTIONAL(structname, fieldname) offsetof(structname, fieldname) +#define PB_DO_PB_HTYPE_REPEATED(structname, fieldname) offsetof(structname, fieldname) +#define PB_DO_PB_HTYPE_FIXARRAY(structname, fieldname) offsetof(structname, fieldname) + +#define PB_SIZE_OFFSET_STATIC(htype, structname, fieldname) PB_SO ## htype(structname, fieldname) +#define PB_SIZE_OFFSET_POINTER(htype, structname, fieldname) PB_SO_PTR ## htype(structname, fieldname) +#define PB_SIZE_OFFSET_CALLBACK(htype, structname, fieldname) PB_SO_CB ## htype(structname, fieldname) +#define PB_SO_PB_HTYPE_REQUIRED(structname, fieldname) 0 +#define PB_SO_PB_HTYPE_SINGULAR(structname, fieldname) 0 +#define PB_SO_PB_HTYPE_ONEOF(structname, fieldname) PB_SO_PB_HTYPE_ONEOF2(structname, PB_ONEOF_NAME(FULL, fieldname), PB_ONEOF_NAME(UNION, fieldname)) +#define PB_SO_PB_HTYPE_ONEOF2(structname, fullname, unionname) PB_SO_PB_HTYPE_ONEOF3(structname, fullname, unionname) +#define PB_SO_PB_HTYPE_ONEOF3(structname, fullname, unionname) pb_delta(structname, fullname, which_ ## unionname) +#define PB_SO_PB_HTYPE_OPTIONAL(structname, fieldname) pb_delta(structname, fieldname, has_ ## fieldname) +#define PB_SO_PB_HTYPE_REPEATED(structname, fieldname) pb_delta(structname, fieldname, fieldname ## _count) +#define PB_SO_PB_HTYPE_FIXARRAY(structname, fieldname) 0 +#define PB_SO_PTR_PB_HTYPE_REQUIRED(structname, fieldname) 0 +#define PB_SO_PTR_PB_HTYPE_SINGULAR(structname, fieldname) 0 +#define PB_SO_PTR_PB_HTYPE_ONEOF(structname, fieldname) PB_SO_PB_HTYPE_ONEOF(structname, fieldname) +#define PB_SO_PTR_PB_HTYPE_OPTIONAL(structname, fieldname) 0 +#define PB_SO_PTR_PB_HTYPE_REPEATED(structname, fieldname) PB_SO_PB_HTYPE_REPEATED(structname, fieldname) +#define PB_SO_PTR_PB_HTYPE_FIXARRAY(structname, fieldname) 0 +#define PB_SO_CB_PB_HTYPE_REQUIRED(structname, fieldname) 0 +#define PB_SO_CB_PB_HTYPE_SINGULAR(structname, fieldname) 0 +#define PB_SO_CB_PB_HTYPE_ONEOF(structname, fieldname) PB_SO_PB_HTYPE_ONEOF(structname, fieldname) +#define PB_SO_CB_PB_HTYPE_OPTIONAL(structname, fieldname) 0 +#define PB_SO_CB_PB_HTYPE_REPEATED(structname, fieldname) 0 +#define PB_SO_CB_PB_HTYPE_FIXARRAY(structname, fieldname) 0 + +#define PB_ARRAY_SIZE_STATIC(htype, structname, fieldname) PB_AS ## htype(structname, fieldname) +#define PB_ARRAY_SIZE_POINTER(htype, structname, fieldname) PB_AS_PTR ## htype(structname, fieldname) #define PB_ARRAY_SIZE_CALLBACK(htype, structname, fieldname) 1 -#define PB_ARRAY_SIZE_REQUIRED(structname, fieldname) 1 -#define PB_ARRAY_SIZE_SINGULAR(structname, fieldname) 1 -#define PB_ARRAY_SIZE_OPTIONAL(structname, fieldname) 1 -#define PB_ARRAY_SIZE_ONEOF(structname, fieldname) 1 -#define PB_ARRAY_SIZE_REPEATED(structname, fieldname) pb_arraysize(structname, fieldname) -#define PB_ARRAY_SIZE_FIXARRAY(structname, fieldname) pb_arraysize(structname, fieldname) - -#define PB_DATA_SIZE_STATIC(htype, structname, fieldname) PB_DATA_SIZE_##htype(structname, fieldname) -#define PB_DATA_SIZE_POINTER(htype, structname, fieldname) PB_DATA_SIZE_PTR_##htype(structname, fieldname) -#define PB_DATA_SIZE_CALLBACK(htype, structname, fieldname) PB_DATA_SIZE_CB_##htype(structname, fieldname) -#define PB_DATA_SIZE_REQUIRED(structname, fieldname) pb_membersize(structname, fieldname) -#define PB_DATA_SIZE_SINGULAR(structname, fieldname) pb_membersize(structname, fieldname) -#define PB_DATA_SIZE_OPTIONAL(structname, fieldname) pb_membersize(structname, fieldname) -#define PB_DATA_SIZE_ONEOF(structname, fieldname) pb_membersize(structname, PB_ONEOF_NAME(FULL, fieldname)) -#define PB_DATA_SIZE_REPEATED(structname, fieldname) pb_membersize(structname, fieldname[0]) -#define PB_DATA_SIZE_FIXARRAY(structname, fieldname) pb_membersize(structname, fieldname[0]) -#define PB_DATA_SIZE_PTR_REQUIRED(structname, fieldname) pb_membersize(structname, fieldname[0]) -#define PB_DATA_SIZE_PTR_SINGULAR(structname, fieldname) pb_membersize(structname, fieldname[0]) -#define PB_DATA_SIZE_PTR_OPTIONAL(structname, fieldname) pb_membersize(structname, fieldname[0]) -#define PB_DATA_SIZE_PTR_ONEOF(structname, fieldname) pb_membersize(structname, PB_ONEOF_NAME(FULL, fieldname)[0]) -#define PB_DATA_SIZE_PTR_REPEATED(structname, fieldname) pb_membersize(structname, fieldname[0]) -#define PB_DATA_SIZE_PTR_FIXARRAY(structname, fieldname) pb_membersize(structname, fieldname[0]) -#define PB_DATA_SIZE_CB_REQUIRED(structname, fieldname) pb_membersize(structname, fieldname) -#define PB_DATA_SIZE_CB_SINGULAR(structname, fieldname) pb_membersize(structname, fieldname) -#define PB_DATA_SIZE_CB_OPTIONAL(structname, fieldname) pb_membersize(structname, fieldname) -#define PB_DATA_SIZE_CB_ONEOF(structname, fieldname) pb_membersize(structname, PB_ONEOF_NAME(FULL, fieldname)) -#define PB_DATA_SIZE_CB_REPEATED(structname, fieldname) pb_membersize(structname, fieldname) -#define PB_DATA_SIZE_CB_FIXARRAY(structname, fieldname) pb_membersize(structname, fieldname) - -#define PB_ONEOF_NAME(type, tuple) PB_EXPAND(PB_ONEOF_NAME_##type tuple) -#define PB_ONEOF_NAME_UNION(unionname, membername, fullname) unionname -#define PB_ONEOF_NAME_MEMBER(unionname, membername, fullname) membername -#define PB_ONEOF_NAME_FULL(unionname, membername, fullname) fullname +#define PB_AS_PB_HTYPE_REQUIRED(structname, fieldname) 1 +#define PB_AS_PB_HTYPE_SINGULAR(structname, fieldname) 1 +#define PB_AS_PB_HTYPE_OPTIONAL(structname, fieldname) 1 +#define PB_AS_PB_HTYPE_ONEOF(structname, fieldname) 1 +#define PB_AS_PB_HTYPE_REPEATED(structname, fieldname) pb_arraysize(structname, fieldname) +#define PB_AS_PB_HTYPE_FIXARRAY(structname, fieldname) pb_arraysize(structname, fieldname) +#define PB_AS_PTR_PB_HTYPE_REQUIRED(structname, fieldname) 1 +#define PB_AS_PTR_PB_HTYPE_SINGULAR(structname, fieldname) 1 +#define PB_AS_PTR_PB_HTYPE_OPTIONAL(structname, fieldname) 1 +#define PB_AS_PTR_PB_HTYPE_ONEOF(structname, fieldname) 1 +#define PB_AS_PTR_PB_HTYPE_REPEATED(structname, fieldname) 1 +#define PB_AS_PTR_PB_HTYPE_FIXARRAY(structname, fieldname) pb_arraysize(structname, fieldname[0]) + +#define PB_DATA_SIZE_STATIC(htype, structname, fieldname) PB_DS ## htype(structname, fieldname) +#define PB_DATA_SIZE_POINTER(htype, structname, fieldname) PB_DS_PTR ## htype(structname, fieldname) +#define PB_DATA_SIZE_CALLBACK(htype, structname, fieldname) PB_DS_CB ## htype(structname, fieldname) +#define PB_DS_PB_HTYPE_REQUIRED(structname, fieldname) pb_membersize(structname, fieldname) +#define PB_DS_PB_HTYPE_SINGULAR(structname, fieldname) pb_membersize(structname, fieldname) +#define PB_DS_PB_HTYPE_OPTIONAL(structname, fieldname) pb_membersize(structname, fieldname) +#define PB_DS_PB_HTYPE_ONEOF(structname, fieldname) pb_membersize(structname, PB_ONEOF_NAME(FULL, fieldname)) +#define PB_DS_PB_HTYPE_REPEATED(structname, fieldname) pb_membersize(structname, fieldname[0]) +#define PB_DS_PB_HTYPE_FIXARRAY(structname, fieldname) pb_membersize(structname, fieldname[0]) +#define PB_DS_PTR_PB_HTYPE_REQUIRED(structname, fieldname) pb_membersize(structname, fieldname[0]) +#define PB_DS_PTR_PB_HTYPE_SINGULAR(structname, fieldname) pb_membersize(structname, fieldname[0]) +#define PB_DS_PTR_PB_HTYPE_OPTIONAL(structname, fieldname) pb_membersize(structname, fieldname[0]) +#define PB_DS_PTR_PB_HTYPE_ONEOF(structname, fieldname) pb_membersize(structname, PB_ONEOF_NAME(FULL, fieldname)[0]) +#define PB_DS_PTR_PB_HTYPE_REPEATED(structname, fieldname) pb_membersize(structname, fieldname[0]) +#define PB_DS_PTR_PB_HTYPE_FIXARRAY(structname, fieldname) pb_membersize(structname, fieldname[0][0]) +#define PB_DS_CB_PB_HTYPE_REQUIRED(structname, fieldname) pb_membersize(structname, fieldname) +#define PB_DS_CB_PB_HTYPE_SINGULAR(structname, fieldname) pb_membersize(structname, fieldname) +#define PB_DS_CB_PB_HTYPE_OPTIONAL(structname, fieldname) pb_membersize(structname, fieldname) +#define PB_DS_CB_PB_HTYPE_ONEOF(structname, fieldname) pb_membersize(structname, PB_ONEOF_NAME(FULL, fieldname)) +#define PB_DS_CB_PB_HTYPE_REPEATED(structname, fieldname) pb_membersize(structname, fieldname) +#define PB_DS_CB_PB_HTYPE_FIXARRAY(structname, fieldname) pb_membersize(structname, fieldname) + +#define PB_ONEOF_NAME(type, tuple) PB_EXPAND(PB_ONEOF_NAME_ ## type tuple) +#define PB_ONEOF_NAME_UNION(unionname,membername,fullname) unionname +#define PB_ONEOF_NAME_MEMBER(unionname,membername,fullname) membername +#define PB_ONEOF_NAME_FULL(unionname,membername,fullname) fullname #define PB_GEN_SUBMSG_INFO(structname, atype, htype, ltype, fieldname, tag) \ - PB_SUBMSG_INFO_##htype(ltype, structname, fieldname) + PB_SUBMSG_INFO_ ## htype(_PB_LTYPE_ ## ltype, structname, fieldname) -#define PB_SUBMSG_INFO_REQUIRED(ltype, structname, fieldname) PB_SUBMSG_INFO_##ltype(structname##_##fieldname##_MSGTYPE) -#define PB_SUBMSG_INFO_SINGULAR(ltype, structname, fieldname) PB_SUBMSG_INFO_##ltype(structname##_##fieldname##_MSGTYPE) -#define PB_SUBMSG_INFO_OPTIONAL(ltype, structname, fieldname) PB_SUBMSG_INFO_##ltype(structname##_##fieldname##_MSGTYPE) +#define PB_SUBMSG_INFO_REQUIRED(ltype, structname, fieldname) PB_SI ## ltype(structname ## _ ## fieldname ## _MSGTYPE) +#define PB_SUBMSG_INFO_SINGULAR(ltype, structname, fieldname) PB_SI ## ltype(structname ## _ ## fieldname ## _MSGTYPE) +#define PB_SUBMSG_INFO_OPTIONAL(ltype, structname, fieldname) PB_SI ## ltype(structname ## _ ## fieldname ## _MSGTYPE) #define PB_SUBMSG_INFO_ONEOF(ltype, structname, fieldname) PB_SUBMSG_INFO_ONEOF2(ltype, structname, PB_ONEOF_NAME(UNION, fieldname), PB_ONEOF_NAME(MEMBER, fieldname)) #define PB_SUBMSG_INFO_ONEOF2(ltype, structname, unionname, membername) PB_SUBMSG_INFO_ONEOF3(ltype, structname, unionname, membername) -#define PB_SUBMSG_INFO_ONEOF3(ltype, structname, unionname, membername) PB_SUBMSG_INFO_##ltype(structname##_##unionname##_##membername##_MSGTYPE) -#define PB_SUBMSG_INFO_REPEATED(ltype, structname, fieldname) PB_SUBMSG_INFO_##ltype(structname##_##fieldname##_MSGTYPE) -#define PB_SUBMSG_INFO_FIXARRAY(ltype, structname, fieldname) PB_SUBMSG_INFO_##ltype(structname##_##fieldname##_MSGTYPE) -#define PB_SUBMSG_INFO_BOOL(t) -#define PB_SUBMSG_INFO_BYTES(t) -#define PB_SUBMSG_INFO_DOUBLE(t) -#define PB_SUBMSG_INFO_ENUM(t) -#define PB_SUBMSG_INFO_UENUM(t) -#define PB_SUBMSG_INFO_FIXED32(t) -#define PB_SUBMSG_INFO_FIXED64(t) -#define PB_SUBMSG_INFO_FLOAT(t) -#define PB_SUBMSG_INFO_INT32(t) -#define PB_SUBMSG_INFO_INT64(t) -#define PB_SUBMSG_INFO_MESSAGE(t) PB_SUBMSG_DESCRIPTOR(t) -#define PB_SUBMSG_INFO_MSG_W_CB(t) PB_SUBMSG_DESCRIPTOR(t) -#define PB_SUBMSG_INFO_SFIXED32(t) -#define PB_SUBMSG_INFO_SFIXED64(t) -#define PB_SUBMSG_INFO_SINT32(t) -#define PB_SUBMSG_INFO_SINT64(t) -#define PB_SUBMSG_INFO_STRING(t) -#define PB_SUBMSG_INFO_UINT32(t) -#define PB_SUBMSG_INFO_UINT64(t) -#define PB_SUBMSG_INFO_EXTENSION(t) -#define PB_SUBMSG_INFO_FIXED_LENGTH_BYTES(t) -#define PB_SUBMSG_DESCRIPTOR(t) &(t##_msg), +#define PB_SUBMSG_INFO_ONEOF3(ltype, structname, unionname, membername) PB_SI ## ltype(structname ## _ ## unionname ## _ ## membername ## _MSGTYPE) +#define PB_SUBMSG_INFO_REPEATED(ltype, structname, fieldname) PB_SI ## ltype(structname ## _ ## fieldname ## _MSGTYPE) +#define PB_SUBMSG_INFO_FIXARRAY(ltype, structname, fieldname) PB_SI ## ltype(structname ## _ ## fieldname ## _MSGTYPE) +#define PB_SI_PB_LTYPE_BOOL(t) +#define PB_SI_PB_LTYPE_BYTES(t) +#define PB_SI_PB_LTYPE_DOUBLE(t) +#define PB_SI_PB_LTYPE_ENUM(t) +#define PB_SI_PB_LTYPE_UENUM(t) +#define PB_SI_PB_LTYPE_FIXED32(t) +#define PB_SI_PB_LTYPE_FIXED64(t) +#define PB_SI_PB_LTYPE_FLOAT(t) +#define PB_SI_PB_LTYPE_INT32(t) +#define PB_SI_PB_LTYPE_INT64(t) +#define PB_SI_PB_LTYPE_MESSAGE(t) PB_SUBMSG_DESCRIPTOR(t) +#define PB_SI_PB_LTYPE_MSG_W_CB(t) PB_SUBMSG_DESCRIPTOR(t) +#define PB_SI_PB_LTYPE_SFIXED32(t) +#define PB_SI_PB_LTYPE_SFIXED64(t) +#define PB_SI_PB_LTYPE_SINT32(t) +#define PB_SI_PB_LTYPE_SINT64(t) +#define PB_SI_PB_LTYPE_STRING(t) +#define PB_SI_PB_LTYPE_UINT32(t) +#define PB_SI_PB_LTYPE_UINT64(t) +#define PB_SI_PB_LTYPE_EXTENSION(t) +#define PB_SI_PB_LTYPE_FIXED_LENGTH_BYTES(t) +#define PB_SUBMSG_DESCRIPTOR(t) &(t ## _msg), /* The field descriptors use a variable width format, with width of either * 1, 2, 4 or 8 of 32-bit words. The two lowest bytes of the first byte always @@ -692,23 +734,23 @@ struct pb_extension_s { * [32-bit reserved] */ -#define PB_FIELDINFO_1(tag, type, data_offset, data_size, size_offset, array_size) \ - (0 | (((tag) << 2) & 0xFF) | ((type) << 8) | (((uint32_t)(data_offset) &0xFF) << 16) | \ - (((uint32_t)(size_offset) &0x0F) << 24) | (((uint32_t)(data_size) &0x0F) << 28)), +#define PB_FIELDINFO_1(tag, type, data_offset, data_size, size_offset, array_size) \ + (0 | (((tag) << 2) & 0xFF) | ((type) << 8) | (((uint32_t)(data_offset) & 0xFF) << 16) | \ + (((uint32_t)(size_offset) & 0x0F) << 24) | (((uint32_t)(data_size) & 0x0F) << 28)), -#define PB_FIELDINFO_2(tag, type, data_offset, data_size, size_offset, array_size) \ - (1 | (((tag) << 2) & 0xFF) | ((type) << 8) | (((uint32_t)(array_size) &0xFFF) << 16) | (((uint32_t)(size_offset) &0x0F) << 28)), \ - (((uint32_t)(data_offset) &0xFFFF) | (((uint32_t)(data_size) &0xFFF) << 16) | (((uint32_t)(tag) &0x2c0) << 22)), +#define PB_FIELDINFO_2(tag, type, data_offset, data_size, size_offset, array_size) \ + (1 | (((tag) << 2) & 0xFF) | ((type) << 8) | (((uint32_t)(array_size) & 0xFFF) << 16) | (((uint32_t)(size_offset) & 0x0F) << 28)), \ + (((uint32_t)(data_offset) & 0xFFFF) | (((uint32_t)(data_size) & 0xFFF) << 16) | (((uint32_t)(tag) & 0x3c0) << 22)), -#define PB_FIELDINFO_4(tag, type, data_offset, data_size, size_offset, array_size) \ - (2 | (((tag) << 2) & 0xFF) | ((type) << 8) | (((uint32_t)(array_size) &0xFFFF) << 16)), \ - ((uint32_t)(int8_t)(size_offset) | (((uint32_t)(tag) << 2) & 0xFFFFFF00)), \ - (data_offset), (data_size), +#define PB_FIELDINFO_4(tag, type, data_offset, data_size, size_offset, array_size) \ + (2 | (((tag) << 2) & 0xFF) | ((type) << 8) | (((uint32_t)(array_size) & 0xFFFF) << 16)), \ + ((uint32_t)(int_least8_t)(size_offset) | (((uint32_t)(tag) << 2) & 0xFFFFFF00)), \ + (data_offset), (data_size), #define PB_FIELDINFO_8(tag, type, data_offset, data_size, size_offset, array_size) \ - (3 | (((tag) << 2) & 0xFF) | ((type) << 8)), \ - ((uint32_t)(int8_t)(size_offset) | (((uint32_t)(tag) << 2) & 0xFFFFFF00)), \ - (data_offset), (data_size), (array_size) + (3 | (((tag) << 2) & 0xFF) | ((type) << 8)), \ + ((uint32_t)(int_least8_t)(size_offset) | (((uint32_t)(tag) << 2) & 0xFFFFFF00)), \ + (data_offset), (data_size), (array_size), 0, 0, 0, /* These assertions verify that the field information fits in the allocated space. * The generator tries to automatically determine the correct width that can fit all @@ -717,92 +759,92 @@ struct pb_extension_s { * you can increase the descriptor width by defining PB_FIELDINFO_WIDTH or by setting * descriptorsize option in .options file. */ -#define PB_FITS(value, bits) ((uint32_t)(value) < ((uint32_t) 1 << bits)) +#define PB_FITS(value,bits) ((uint32_t)(value) < ((uint32_t)1<2GB messages with nanopb anyway. */ #define PB_FIELDINFO_ASSERT_4(tag, type, data_offset, data_size, size_offset, array_size) \ - PB_STATIC_ASSERT(PB_FITS(tag, 30) && PB_FITS(data_offset, 31) && PB_FITS((int8_t) size_offset, 8) && PB_FITS(data_size, 31) && PB_FITS(array_size, 16), FIELDINFO_DOES_NOT_FIT_width4_field##tag) + PB_STATIC_ASSERT(PB_FITS(tag,30) && PB_FITS(data_offset,31) && PB_FITS(size_offset,8) && PB_FITS(data_size,31) && PB_FITS(array_size,16), FIELDINFO_DOES_NOT_FIT_width4_field ## tag) #define PB_FIELDINFO_ASSERT_8(tag, type, data_offset, data_size, size_offset, array_size) \ - PB_STATIC_ASSERT(PB_FITS(tag, 30) && PB_FITS(data_offset, 31) && PB_FITS((int8_t) size_offset, 8) && PB_FITS(data_size, 31) && PB_FITS(array_size, 31), FIELDINFO_DOES_NOT_FIT_width8_field##tag) + PB_STATIC_ASSERT(PB_FITS(tag,30) && PB_FITS(data_offset,31) && PB_FITS(size_offset,8) && PB_FITS(data_size,31) && PB_FITS(array_size,31), FIELDINFO_DOES_NOT_FIT_width8_field ## tag) #endif + /* Automatic picking of FIELDINFO width: * Uses width 1 when possible, otherwise resorts to width 2. + * This is used when PB_BIND() is called with "AUTO" as the argument. + * The generator will give explicit size argument when it knows that a message + * structure grows beyond 1-word format limits. */ - -#ifndef PB_FIELDINFO_WIDTH -#define PB_FIELDINFO_WIDTH_AUTO(atype, htype, ltype) PB_FIELDINFO_WIDTH_##atype(htype, ltype) -#define PB_FIELDINFO_WIDTH_STATIC(htype, ltype) PB_FIELDINFO_WIDTH_##htype(ltype) -#define PB_FIELDINFO_WIDTH_POINTER(htype, ltype) PB_FIELDINFO_WIDTH_##htype(ltype) -#define PB_FIELDINFO_WIDTH_CALLBACK(htype, ltype) 2 -#define PB_FIELDINFO_WIDTH_REQUIRED(ltype) PB_FIELDINFO_WIDTH_##ltype -#define PB_FIELDINFO_WIDTH_SINGULAR(ltype) PB_FIELDINFO_WIDTH_##ltype -#define PB_FIELDINFO_WIDTH_OPTIONAL(ltype) PB_FIELDINFO_WIDTH_##ltype -#define PB_FIELDINFO_WIDTH_ONEOF(ltype) PB_FIELDINFO_WIDTH_##ltype -#define PB_FIELDINFO_WIDTH_REPEATED(ltype) 2 -#define PB_FIELDINFO_WIDTH_FIXARRAY(ltype) 2 -#define PB_FIELDINFO_WIDTH_BOOL 1 -#define PB_FIELDINFO_WIDTH_BYTES 2 -#define PB_FIELDINFO_WIDTH_DOUBLE 1 -#define PB_FIELDINFO_WIDTH_ENUM 1 -#define PB_FIELDINFO_WIDTH_UENUM 1 -#define PB_FIELDINFO_WIDTH_FIXED32 1 -#define PB_FIELDINFO_WIDTH_FIXED64 1 -#define PB_FIELDINFO_WIDTH_FLOAT 1 -#define PB_FIELDINFO_WIDTH_INT32 1 -#define PB_FIELDINFO_WIDTH_INT64 1 -#define PB_FIELDINFO_WIDTH_MESSAGE 2 -#define PB_FIELDINFO_WIDTH_SFIXED32 1 -#define PB_FIELDINFO_WIDTH_SFIXED64 1 -#define PB_FIELDINFO_WIDTH_SINT32 1 -#define PB_FIELDINFO_WIDTH_SINT64 1 -#define PB_FIELDINFO_WIDTH_STRING 2 -#define PB_FIELDINFO_WIDTH_UINT32 1 -#define PB_FIELDINFO_WIDTH_UINT64 1 -#define PB_FIELDINFO_WIDTH_EXTENSION 1 -#define PB_FIELDINFO_WIDTH_FIXED_LENGTH_BYTES 2 -#else -#define PB_FIELDINFO_WIDTH_AUTO(atype, htype, ltype) PB_FIELDINFO_WIDTH -#endif +#define PB_FIELDINFO_WIDTH_AUTO(atype, htype, ltype) PB_FI_WIDTH ## atype(htype, ltype) +#define PB_FI_WIDTH_PB_ATYPE_STATIC(htype, ltype) PB_FI_WIDTH ## htype(ltype) +#define PB_FI_WIDTH_PB_ATYPE_POINTER(htype, ltype) PB_FI_WIDTH ## htype(ltype) +#define PB_FI_WIDTH_PB_ATYPE_CALLBACK(htype, ltype) 2 +#define PB_FI_WIDTH_PB_HTYPE_REQUIRED(ltype) PB_FI_WIDTH ## ltype +#define PB_FI_WIDTH_PB_HTYPE_SINGULAR(ltype) PB_FI_WIDTH ## ltype +#define PB_FI_WIDTH_PB_HTYPE_OPTIONAL(ltype) PB_FI_WIDTH ## ltype +#define PB_FI_WIDTH_PB_HTYPE_ONEOF(ltype) PB_FI_WIDTH ## ltype +#define PB_FI_WIDTH_PB_HTYPE_REPEATED(ltype) 2 +#define PB_FI_WIDTH_PB_HTYPE_FIXARRAY(ltype) 2 +#define PB_FI_WIDTH_PB_LTYPE_BOOL 1 +#define PB_FI_WIDTH_PB_LTYPE_BYTES 2 +#define PB_FI_WIDTH_PB_LTYPE_DOUBLE 1 +#define PB_FI_WIDTH_PB_LTYPE_ENUM 1 +#define PB_FI_WIDTH_PB_LTYPE_UENUM 1 +#define PB_FI_WIDTH_PB_LTYPE_FIXED32 1 +#define PB_FI_WIDTH_PB_LTYPE_FIXED64 1 +#define PB_FI_WIDTH_PB_LTYPE_FLOAT 1 +#define PB_FI_WIDTH_PB_LTYPE_INT32 1 +#define PB_FI_WIDTH_PB_LTYPE_INT64 1 +#define PB_FI_WIDTH_PB_LTYPE_MESSAGE 2 +#define PB_FI_WIDTH_PB_LTYPE_MSG_W_CB 2 +#define PB_FI_WIDTH_PB_LTYPE_SFIXED32 1 +#define PB_FI_WIDTH_PB_LTYPE_SFIXED64 1 +#define PB_FI_WIDTH_PB_LTYPE_SINT32 1 +#define PB_FI_WIDTH_PB_LTYPE_SINT64 1 +#define PB_FI_WIDTH_PB_LTYPE_STRING 2 +#define PB_FI_WIDTH_PB_LTYPE_UINT32 1 +#define PB_FI_WIDTH_PB_LTYPE_UINT64 1 +#define PB_FI_WIDTH_PB_LTYPE_EXTENSION 1 +#define PB_FI_WIDTH_PB_LTYPE_FIXED_LENGTH_BYTES 2 /* The mapping from protobuf types to LTYPEs is done using these macros. */ -#define PB_LTYPE_MAP_BOOL PB_LTYPE_BOOL -#define PB_LTYPE_MAP_BYTES PB_LTYPE_BYTES -#define PB_LTYPE_MAP_DOUBLE PB_LTYPE_FIXED64 -#define PB_LTYPE_MAP_ENUM PB_LTYPE_VARINT -#define PB_LTYPE_MAP_UENUM PB_LTYPE_UVARINT -#define PB_LTYPE_MAP_FIXED32 PB_LTYPE_FIXED32 -#define PB_LTYPE_MAP_FIXED64 PB_LTYPE_FIXED64 -#define PB_LTYPE_MAP_FLOAT PB_LTYPE_FIXED32 -#define PB_LTYPE_MAP_INT32 PB_LTYPE_VARINT -#define PB_LTYPE_MAP_INT64 PB_LTYPE_VARINT -#define PB_LTYPE_MAP_MESSAGE PB_LTYPE_SUBMESSAGE -#define PB_LTYPE_MAP_MSG_W_CB PB_LTYPE_SUBMSG_W_CB -#define PB_LTYPE_MAP_SFIXED32 PB_LTYPE_FIXED32 -#define PB_LTYPE_MAP_SFIXED64 PB_LTYPE_FIXED64 -#define PB_LTYPE_MAP_SINT32 PB_LTYPE_SVARINT -#define PB_LTYPE_MAP_SINT64 PB_LTYPE_SVARINT -#define PB_LTYPE_MAP_STRING PB_LTYPE_STRING -#define PB_LTYPE_MAP_UINT32 PB_LTYPE_UVARINT -#define PB_LTYPE_MAP_UINT64 PB_LTYPE_UVARINT -#define PB_LTYPE_MAP_EXTENSION PB_LTYPE_EXTENSION +#define PB_LTYPE_MAP_BOOL PB_LTYPE_BOOL +#define PB_LTYPE_MAP_BYTES PB_LTYPE_BYTES +#define PB_LTYPE_MAP_DOUBLE PB_LTYPE_FIXED64 +#define PB_LTYPE_MAP_ENUM PB_LTYPE_VARINT +#define PB_LTYPE_MAP_UENUM PB_LTYPE_UVARINT +#define PB_LTYPE_MAP_FIXED32 PB_LTYPE_FIXED32 +#define PB_LTYPE_MAP_FIXED64 PB_LTYPE_FIXED64 +#define PB_LTYPE_MAP_FLOAT PB_LTYPE_FIXED32 +#define PB_LTYPE_MAP_INT32 PB_LTYPE_VARINT +#define PB_LTYPE_MAP_INT64 PB_LTYPE_VARINT +#define PB_LTYPE_MAP_MESSAGE PB_LTYPE_SUBMESSAGE +#define PB_LTYPE_MAP_MSG_W_CB PB_LTYPE_SUBMSG_W_CB +#define PB_LTYPE_MAP_SFIXED32 PB_LTYPE_FIXED32 +#define PB_LTYPE_MAP_SFIXED64 PB_LTYPE_FIXED64 +#define PB_LTYPE_MAP_SINT32 PB_LTYPE_SVARINT +#define PB_LTYPE_MAP_SINT64 PB_LTYPE_SVARINT +#define PB_LTYPE_MAP_STRING PB_LTYPE_STRING +#define PB_LTYPE_MAP_UINT32 PB_LTYPE_UVARINT +#define PB_LTYPE_MAP_UINT64 PB_LTYPE_UVARINT +#define PB_LTYPE_MAP_EXTENSION PB_LTYPE_EXTENSION #define PB_LTYPE_MAP_FIXED_LENGTH_BYTES PB_LTYPE_FIXED_LENGTH_BYTES /* These macros are used for giving out error messages. @@ -834,21 +876,20 @@ struct pb_extension_s { #ifdef __cplusplus #if __cplusplus >= 201103L #define PB_CONSTEXPR constexpr -#else // __cplusplus >= 201103L +#else // __cplusplus >= 201103L #define PB_CONSTEXPR -#endif // __cplusplus >= 201103L +#endif // __cplusplus >= 201103L #if __cplusplus >= 201703L #define PB_INLINE_CONSTEXPR inline constexpr -#else // __cplusplus >= 201703L +#else // __cplusplus >= 201703L #define PB_INLINE_CONSTEXPR PB_CONSTEXPR -#endif // __cplusplus >= 201703L +#endif // __cplusplus >= 201703L namespace nanopb { // Each type will be partially specialized by the generator. -template -struct MessageDescriptor; -} // namespace nanopb -#endif /* __cplusplus */ +template struct MessageDescriptor; +} // namespace nanopb +#endif /* __cplusplus */ -#endif +#endif \ No newline at end of file From 6c68f6488c5612e43cdfb8075145188258be8166 Mon Sep 17 00:00:00 2001 From: Leonardo Souza Date: Fri, 24 Sep 2021 13:01:14 +0200 Subject: [PATCH 077/101] implement serialization function for btc transactions --- c/src/verifier/btc/btc_serialize.c | 58 +++++++++++++++++++++++++ c/src/verifier/btc/btc_serialize.h | 4 ++ c/src/verifier/btc/btc_types.c | 69 ++++++++++++++++++++++++++++++ c/src/verifier/btc/btc_types.h | 1 + 4 files changed, 132 insertions(+) diff --git a/c/src/verifier/btc/btc_serialize.c b/c/src/verifier/btc/btc_serialize.c index bdf9c6736..cd610ed6a 100644 --- a/c/src/verifier/btc/btc_serialize.c +++ b/c/src/verifier/btc/btc_serialize.c @@ -68,6 +68,64 @@ uint64_t le_to_long(uint8_t* data) { (((uint64_t) data[3]) << 24) | (((uint64_t) data[2]) << 16) | (((uint64_t) data[1]) << 8) | data[0]; } +void uint_to_le(bytes_t* buf, uint32_t index, uint32_t value) { + buf->data[index] = value & 0xff; + buf->data[index + 1] = (value >> 8) & 0xff; + buf->data[index + 2] = (value >> 16) & 0xff; + buf->data[index + 3] = (value >> 24) & 0xff; +} + +void uint_to_long(bytes_t* buf, uint32_t index, uint64_t value) { + buf->data[index] = value & 0xff; + buf->data[index + 1] = (value >> 8) & 0xff; + buf->data[index + 2] = (value >> 16) & 0xff; + buf->data[index + 3] = (value >> 24) & 0xff; + buf->data[index + 4] = (value >> 32) & 0xff; + buf->data[index + 5] = (value >> 40) & 0xff; + buf->data[index + 6] = (value >> 48) & 0xff; + buf->data[index + 7] = (value >> 56) & 0xff; +} + +size_t get_compact_uint_size(uint64_t cmpt_uint) { + if (cmpt_uint > 0xffffffff) { + return 9; + } + if (cmpt_uint > 0xffff) { + return 5; + } + if (cmpt_uint > 0xfc) { + return 3; + } + return 1; +} + +void long_to_compact_uint(bytes_t* buf, uint32_t index, uint64_t value) { + int len; + if (value > 0xffffffff) { + len = 9; + buf->data[index] = 0xff; + } + else if (value > 0xffff) { + len = 5; + buf->data[index] = 0xfe; + } + else if (value > 0xfc) { + len = 3; + buf->data[index] = 0xfd; + } + else { + len = 1; + buf->data[index] = (uint8_t) (value & 0xff); + } + + // fill buffer with value + if (len > 1) { + for (int i = 0; i < (len - 1); i++) { + buf->data[i + index] = (uint8_t) ((value >> (i << 1)) && 0xff); + } + } +} + void btc_target_from_block(bytes_t block, bytes32_t target) { uint8_t *bits = btc_block_get(block, BTC_B_BITS).data, tmp[32]; memset(tmp, 0, 32); diff --git a/c/src/verifier/btc/btc_serialize.h b/c/src/verifier/btc/btc_serialize.h index db3e0e700..07572eb91 100644 --- a/c/src/verifier/btc/btc_serialize.h +++ b/c/src/verifier/btc/btc_serialize.h @@ -33,5 +33,9 @@ int btc_get_transactions(bytes_t block, bytes_t* dst); bytes_t btc_get_transaction_end(uint8_t* data); bytes_t btc_get_txinput(uint8_t* data); bytes_t btc_get_txoutput(uint8_t* data); +void uint_to_le(bytes_t* buf, uint32_t index, uint32_t value); +void uint_to_long(bytes_t* buf, uint32_t index, uint64_t value); +size_t get_compact_uint_size(uint64_t cmpt_uint); +void long_to_compact_uint(bytes_t* buf, uint32_t index, uint64_t value); #endif // _BTC_SERIALIZE_H \ No newline at end of file diff --git a/c/src/verifier/btc/btc_types.c b/c/src/verifier/btc/btc_types.c index d75c6e551..147ec0442 100644 --- a/c/src/verifier/btc/btc_types.c +++ b/c/src/verifier/btc/btc_types.c @@ -2,6 +2,9 @@ #include "../../core/util/mem.h" #include "btc_serialize.h" +#define BTC_TX_VERSION_SIZE_BYTES 4 +#define BTC_TX_LOCKTIME_SIZE_BYTES 4 + uint8_t* btc_parse_tx_in(uint8_t* data, btc_tx_in_t* dst, uint8_t* limit) { uint64_t len; dst->prev_tx_hash = data; @@ -55,6 +58,72 @@ in3_ret_t btc_parse_tx(bytes_t tx, btc_tx_t* dst) { return IN3_OK; } +// Converts a btc transaction into a serialized transaction +// TODO: Implement serialization for when tx_in and tx_out are not NULL +// WARNING: You need to free dst pointer after using this function! +in3_ret_t btc_serialize_transaction(btc_tx_t* tx, btc_tx_in_t* tx_in, btc_tx_out_t* tx_out, bytes_t* dst) { + UNUSED_VAR(tx_in); + UNUSED_VAR(tx_out); + + // Clean exit buffer + dst->len = 0; + + // calculate transaction size in bytes + uint32_t tx_size; + tx_size = (BTC_TX_VERSION_SIZE_BYTES + + (2 * tx->flag) + + get_compact_uint_size((uint64_t) tx->input_count) + + tx->input.len + + get_compact_uint_size((uint64_t) tx->output_count) + + tx->output.len + + tx->witnesses.len + + BTC_TX_LOCKTIME_SIZE_BYTES); + + dst->data = malloc(tx_size * sizeof(*dst->data)); + dst->len = tx_size; + + // Serialize transaction data + uint32_t index = 0; + // version + uint_to_le(dst, index, tx->version); + index += 4; + // Check if transaction uses SegWit + if (tx->flag) { + dst->data[index++] = 0; + dst->data[index++] = 1; + } + // input_count + long_to_compact_uint(dst, index, tx->input_count); + index += get_compact_uint_size(tx->input_count); + // inputs + // TODO: serialize struct if tx_in is not null + for (uint32_t i = 0; i < tx->input.len; i++) { + dst->data[index++] = tx->input.data[i]; + } + // output_count + long_to_compact_uint(dst, index, tx->output_count); + index += get_compact_uint_size(tx->output_count); + // outputs + // TODO: serialize struct if tx_out is not null + for (uint32_t i = 0; i < tx->output.len; i++) { + dst->data[index++] = tx->output.data[i]; + } + // Include witness + if (tx->flag) { + for (uint32_t i = 0; i < tx->witnesses.len; i++) { + dst->data[index++] = tx->witnesses.data[i]; + } + } + // locktime + //uint_to_le(dst, index, tx->lock_time); + dst->data[index + 3] = ((tx->lock_time >> 24) & 0xff); + dst->data[index + 2] = ((tx->lock_time >> 16) & 0xff); + dst->data[index + 1] = ((tx->lock_time >> 8) & 0xff); + dst->data[index] = ((tx->lock_time) & 0xff); + + return IN3_OK; +} + uint32_t btc_vsize(btc_tx_t* tx) { uint32_t w = btc_weight(tx); return w % 4 ? (w + 4) / 4 : w / 4; diff --git a/c/src/verifier/btc/btc_types.h b/c/src/verifier/btc/btc_types.h index a86ae4e05..40dfab15c 100644 --- a/c/src/verifier/btc/btc_types.h +++ b/c/src/verifier/btc/btc_types.h @@ -34,6 +34,7 @@ in3_ret_t btc_parse_tx(bytes_t tx, btc_tx_t* dst); in3_ret_t btc_tx_id(btc_tx_t* tx, bytes32_t dst); uint8_t* btc_parse_tx_in(uint8_t* data, btc_tx_in_t* dst, uint8_t* limit); uint8_t* btc_parse_tx_out(uint8_t* data, btc_tx_out_t* dst); +in3_ret_t btc_serialize_transaction(btc_tx_t* tx, bytes_t* dst); uint32_t btc_vsize(btc_tx_t* tx); uint32_t btc_weight(btc_tx_t* tx); From fc90e67b68c2e633a206aebfeb5c779961b6abf0 Mon Sep 17 00:00:00 2001 From: Leonardo Souza Date: Tue, 28 Sep 2021 13:00:22 +0200 Subject: [PATCH 078/101] Implement serialize for tx in and out --- c/src/verifier/btc/btc_serialize.c | 5 +- c/src/verifier/btc/btc_serialize.h | 2 +- c/src/verifier/btc/btc_types.c | 83 ++++++++++++++++++++++++++++-- c/src/verifier/btc/btc_types.h | 15 ++++-- 4 files changed, 93 insertions(+), 12 deletions(-) diff --git a/c/src/verifier/btc/btc_serialize.c b/c/src/verifier/btc/btc_serialize.c index cd610ed6a..061b8066d 100644 --- a/c/src/verifier/btc/btc_serialize.c +++ b/c/src/verifier/btc/btc_serialize.c @@ -68,6 +68,7 @@ uint64_t le_to_long(uint8_t* data) { (((uint64_t) data[3]) << 24) | (((uint64_t) data[2]) << 16) | (((uint64_t) data[1]) << 8) | data[0]; } +// TODO: Receive 'buf' as type 'uint8_t*' instead of 'bytes_t*' void uint_to_le(bytes_t* buf, uint32_t index, uint32_t value) { buf->data[index] = value & 0xff; buf->data[index + 1] = (value >> 8) & 0xff; @@ -75,7 +76,8 @@ void uint_to_le(bytes_t* buf, uint32_t index, uint32_t value) { buf->data[index + 3] = (value >> 24) & 0xff; } -void uint_to_long(bytes_t* buf, uint32_t index, uint64_t value) { +// TODO: Receive 'buf' as type 'uint8_t*' instead of 'bytes_t*' +void long_to_le(bytes_t* buf, uint32_t index, uint64_t value) { buf->data[index] = value & 0xff; buf->data[index + 1] = (value >> 8) & 0xff; buf->data[index + 2] = (value >> 16) & 0xff; @@ -99,6 +101,7 @@ size_t get_compact_uint_size(uint64_t cmpt_uint) { return 1; } +// TODO: Receive 'buf' as type 'uint8_t*' instead of 'bytes_t*' void long_to_compact_uint(bytes_t* buf, uint32_t index, uint64_t value) { int len; if (value > 0xffffffff) { diff --git a/c/src/verifier/btc/btc_serialize.h b/c/src/verifier/btc/btc_serialize.h index 07572eb91..874060092 100644 --- a/c/src/verifier/btc/btc_serialize.h +++ b/c/src/verifier/btc/btc_serialize.h @@ -34,7 +34,7 @@ bytes_t btc_get_transaction_end(uint8_t* data); bytes_t btc_get_txinput(uint8_t* data); bytes_t btc_get_txoutput(uint8_t* data); void uint_to_le(bytes_t* buf, uint32_t index, uint32_t value); -void uint_to_long(bytes_t* buf, uint32_t index, uint64_t value); +void long_to_le(bytes_t* buf, uint32_t index, uint64_t value); size_t get_compact_uint_size(uint64_t cmpt_uint); void long_to_compact_uint(bytes_t* buf, uint32_t index, uint64_t value); diff --git a/c/src/verifier/btc/btc_types.c b/c/src/verifier/btc/btc_types.c index 147ec0442..c079c5631 100644 --- a/c/src/verifier/btc/btc_types.c +++ b/c/src/verifier/btc/btc_types.c @@ -2,9 +2,17 @@ #include "../../core/util/mem.h" #include "btc_serialize.h" +// Transaction fixed size values #define BTC_TX_VERSION_SIZE_BYTES 4 #define BTC_TX_LOCKTIME_SIZE_BYTES 4 +// Input fixed size values +#define BTC_TX_IN_PREV_OUPUT_SIZE_BYTES 36 // Outpoint = prev txid (32 bytes) + output index (4 bytes) +#define BTC_TX_IN_SEQUENCE_SIZE_BYTES 4 + +// Output fixed size values +#define BTC_TX_OUT_VALUE_SIZE_BYTES 8 + uint8_t* btc_parse_tx_in(uint8_t* data, btc_tx_in_t* dst, uint8_t* limit) { uint64_t len; dst->prev_tx_hash = data; @@ -16,6 +24,44 @@ uint8_t* btc_parse_tx_in(uint8_t* data, btc_tx_in_t* dst, uint8_t* limit) { return dst->script.data + dst->script.len + 4; } +// WARNING: You need to free 'dst' pointer after calling this function +// TODO: Implement support for "Coinbase" inputs +// TODO: Handle null arguments +// TODO: Handle max script len = 10000 bytes +void btc_serialize_tx_in(btc_tx_in_t* tx_in, bytes_t* dst) { + if (!tx_in || !dst) return; + // calculate serialized tx input size in bytes + uint32_t tx_in_size = (BTC_TX_IN_PREV_OUPUT_SIZE_BYTES + + get_compact_uint_size((uint64_t) tx_in->script.len) + + tx_in->script.len + + BTC_TX_IN_SEQUENCE_SIZE_BYTES); + + // alloc memory in dst + dst->data = malloc(tx_in_size * sizeof(*dst->data)); + dst->len = tx_in_size; + + // serialize tx_in + // -- Previous outpoint + if (!tx_in->prev_tx_hash) return; + uint32_t index = 0; + for (uint32_t i = 0; i < 32; i++) { + dst->data[index++] = tx_in->prev_tx_hash[i]; + } + uint_to_le(dst, index, tx_in->prev_tx_index); + index += 4; + + // -- script + long_to_compact_uint(dst, index, tx_in->script.len); + index += get_compact_uint_size(tx_in->script.len); + + for (uint32_t i = 0; i < tx_in->script.len; i++) { + dst->data[index++] = tx_in->script.data[i]; + } + + // -- sequence + uint_to_le(dst, index, tx_in->sequence); +} + uint8_t* btc_parse_tx_out(uint8_t* data, btc_tx_out_t* dst) { uint64_t len; dst->value = le_to_long(data); @@ -24,6 +70,36 @@ uint8_t* btc_parse_tx_out(uint8_t* data, btc_tx_out_t* dst) { return dst->script.data + dst->script.len; } +// WARNING: You need to free 'dst' pointer after calling this function +// TODO: Handle null arguments +// TODO: Handle max script len = 10000 bytes +void btc_serialize_tx_out(btc_tx_out_t* tx_out, bytes_t* dst) { + // calculate serialized tx output size in bytes + uint32_t tx_out_size = (BTC_TX_OUT_VALUE_SIZE_BYTES + + get_compact_uint_size((uint64_t) tx_out->script.len) + + tx_out->script.len); + + // alloc memory in dst + dst->data = malloc(tx_out_size * sizeof(*dst->data)); + dst->len = tx_out_size; + + // serialize tx_out + uint32_t index = 0; + + // -- value + long_to_le(dst, index, tx_out->value); + index += 8; + + // -- pk_script size + long_to_compact_uint(dst, index, tx_out->script.len); + index += get_compact_uint_size((uint64_t) tx_out->script.len); + + // -- pk_script + for (uint32_t i = 0; i < tx_out->script.len; i++) { + dst->data[index++] = tx_out->script.data[i]; + } +} + in3_ret_t btc_parse_tx(bytes_t tx, btc_tx_t* dst) { uint64_t val; btc_tx_in_t tx_in; @@ -59,12 +135,9 @@ in3_ret_t btc_parse_tx(bytes_t tx, btc_tx_t* dst) { } // Converts a btc transaction into a serialized transaction -// TODO: Implement serialization for when tx_in and tx_out are not NULL // WARNING: You need to free dst pointer after using this function! -in3_ret_t btc_serialize_transaction(btc_tx_t* tx, btc_tx_in_t* tx_in, btc_tx_out_t* tx_out, bytes_t* dst) { - UNUSED_VAR(tx_in); - UNUSED_VAR(tx_out); - +// TODO: Error handling for null tx and dst pointers +in3_ret_t btc_serialize_tx(btc_tx_t* tx, bytes_t* dst) { // Clean exit buffer dst->len = 0; diff --git a/c/src/verifier/btc/btc_types.h b/c/src/verifier/btc/btc_types.h index 40dfab15c..3a7822ff1 100644 --- a/c/src/verifier/btc/btc_types.h +++ b/c/src/verifier/btc/btc_types.h @@ -31,12 +31,17 @@ typedef struct btc_tx_out { } btc_tx_out_t; in3_ret_t btc_parse_tx(bytes_t tx, btc_tx_t* dst); +in3_ret_t btc_serialize_tx(btc_tx_t* tx, bytes_t* dst); in3_ret_t btc_tx_id(btc_tx_t* tx, bytes32_t dst); -uint8_t* btc_parse_tx_in(uint8_t* data, btc_tx_in_t* dst, uint8_t* limit); -uint8_t* btc_parse_tx_out(uint8_t* data, btc_tx_out_t* dst); -in3_ret_t btc_serialize_transaction(btc_tx_t* tx, bytes_t* dst); -uint32_t btc_vsize(btc_tx_t* tx); -uint32_t btc_weight(btc_tx_t* tx); + +uint8_t* btc_parse_tx_in(uint8_t* data, btc_tx_in_t* dst, uint8_t* limit); +void btc_serialize_tx_in(btc_tx_in_t* tx_in, bytes_t* dst); + +uint8_t* btc_parse_tx_out(uint8_t* data, btc_tx_out_t* dst); +void btc_serialize_tx_out(btc_tx_out_t* tx_out, bytes_t* dst); + +uint32_t btc_vsize(btc_tx_t* tx); +uint32_t btc_weight(btc_tx_t* tx); static inline bool btc_is_witness(bytes_t tx) { return tx.data[4] == 0 && tx.data[5] == 1; From 8cea3766123cd687172dda64204623f735319757 Mon Sep 17 00:00:00 2001 From: Leonardo Souza Date: Tue, 12 Oct 2021 13:58:37 +0200 Subject: [PATCH 079/101] Implement BTC input signer --- c/src/verifier/btc/CMakeLists.txt | 1 + c/src/verifier/btc/btc_script.h | 149 +++++++++++++++++++++++++++++ c/src/verifier/btc/btc_serialize.c | 2 + c/src/verifier/btc/btc_sign.c | 111 +++++++++++++++++++++ c/src/verifier/btc/btc_sign.h | 14 +++ c/src/verifier/btc/btc_types.c | 65 +++++++++++++ c/src/verifier/btc/btc_types.h | 2 + 7 files changed, 344 insertions(+) create mode 100644 c/src/verifier/btc/btc_script.h create mode 100644 c/src/verifier/btc/btc_sign.c create mode 100644 c/src/verifier/btc/btc_sign.h diff --git a/c/src/verifier/btc/CMakeLists.txt b/c/src/verifier/btc/CMakeLists.txt index 381b53572..0bc60bbb6 100644 --- a/c/src/verifier/btc/CMakeLists.txt +++ b/c/src/verifier/btc/CMakeLists.txt @@ -41,6 +41,7 @@ add_static_library( btc_types.c btc_serialize.c btc_target.c + btc_sign.c btc.c DEPENDS diff --git a/c/src/verifier/btc/btc_script.h b/c/src/verifier/btc/btc_script.h new file mode 100644 index 000000000..bd9a9d9cb --- /dev/null +++ b/c/src/verifier/btc/btc_script.h @@ -0,0 +1,149 @@ +#ifndef _BTC_SCRIPT_H +#define _BTC_SCRIPT_H + +#define MAX_SCRIPT_SIZE_BYTES 10000 +#define MAX_STACK_SIZE_BYTES 1000 +#define MAX_OPS_PER_SCRIPT 201 + +typedef enum btc_opcode { + // push value + OP_0 = 0x00, + OP_FALSE = OP_0, + OP_PUSHDATA1 = 0x4c, + OP_PUSHDATA2 = 0x4d, + OP_PUSHDATA4 = 0x4e, + OP_1NEGATE = 0x4f, + OP_RESERVED = 0x50, + OP_1 = 0x51, + OP_TRUE = OP_1, + OP_2 = 0x52, + OP_3 = 0x53, + OP_4 = 0x54, + OP_5 = 0x55, + OP_6 = 0x56, + OP_7 = 0x57, + OP_8 = 0x58, + OP_9 = 0x59, + OP_10 = 0x5a, + OP_11 = 0x5b, + OP_12 = 0x5c, + OP_13 = 0x5d, + OP_14 = 0x5e, + OP_15 = 0x5f, + OP_16 = 0x60, + + // control + OP_NOP = 0x61, + OP_VER = 0x62, + OP_IF = 0x63, + OP_NOTIF = 0x64, + OP_VERIF = 0x65, + OP_VERNOTIF = 0x66, + OP_ELSE = 0x67, + OP_ENDIF = 0x68, + OP_VERIFY = 0x69, + OP_RETURN = 0x6a, + + // stack ops + OP_TOALTSTACK = 0x6b, + OP_FROMALTSTACK = 0x6c, + OP_2DROP = 0x6d, + OP_2DUP = 0x6e, + OP_3DUP = 0x6f, + OP_2OVER = 0x70, + OP_2ROT = 0x71, + OP_2SWAP = 0x72, + OP_IFDUP = 0x73, + OP_DEPTH = 0x74, + OP_DROP = 0x75, + OP_DUP = 0x76, + OP_NIP = 0x77, + OP_OVER = 0x78, + OP_PICK = 0x79, + OP_ROLL = 0x7a, + OP_ROT = 0x7b, + OP_SWAP = 0x7c, + OP_TUCK = 0x7d, + + // splice ops + OP_CAT = 0x7e, + OP_SUBSTR = 0x7f, + OP_LEFT = 0x80, + OP_RIGHT = 0x81, + OP_SIZE = 0x82, + + // bit logic + OP_INVERT = 0x83, + OP_AND = 0x84, + OP_OR = 0x85, + OP_XOR = 0x86, + OP_EQUAL = 0x87, + OP_EQUALVERIFY = 0x88, + OP_RESERVED1 = 0x89, + OP_RESERVED2 = 0x8a, + + // numeric + OP_1ADD = 0x8b, + OP_1SUB = 0x8c, + OP_2MUL = 0x8d, + OP_2DIV = 0x8e, + OP_NEGATE = 0x8f, + OP_ABS = 0x90, + OP_NOT = 0x91, + OP_0NOTEQUAL = 0x92, + + OP_ADD = 0x93, + OP_SUB = 0x94, + OP_MUL = 0x95, + OP_DIV = 0x96, + OP_MOD = 0x97, + OP_LSHIFT = 0x98, + OP_RSHIFT = 0x99, + + OP_BOOLAND = 0x9a, + OP_BOOLOR = 0x9b, + OP_NUMEQUAL = 0x9c, + OP_NUMEQUALVERIFY = 0x9d, + OP_NUMNOTEQUAL = 0x9e, + OP_LESSTHAN = 0x9f, + OP_GREATERTHAN = 0xa0, + OP_LESSTHANOREQUAL = 0xa1, + OP_GREATERTHANOREQUAL = 0xa2, + OP_MIN = 0xa3, + OP_MAX = 0xa4, + + OP_WITHIN = 0xa5, + + // crypto + OP_RIPEMD160 = 0xa6, + OP_SHA1 = 0xa7, + OP_SHA256 = 0xa8, + OP_HASH160 = 0xa9, + OP_HASH256 = 0xaa, + OP_CODESEPARATOR = 0xab, + OP_CHECKSIG = 0xac, + OP_CHECKSIGVERIFY = 0xad, + OP_CHECKMULTISIG = 0xae, + OP_CHECKMULTISIGVERIFY = 0xaf, + + // expansion + OP_NOP1 = 0xb0, + OP_CHECKLOCKTIMEVERIFY = 0xb1, + OP_NOP2 = OP_CHECKLOCKTIMEVERIFY, + OP_CHECKSEQUENCEVERIFY = 0xb2, + OP_NOP3 = OP_CHECKSEQUENCEVERIFY, + OP_NOP4 = 0xb3, + OP_NOP5 = 0xb4, + OP_NOP6 = 0xb5, + OP_NOP7 = 0xb6, + OP_NOP8 = 0xb7, + OP_NOP9 = 0xb8, + OP_NOP10 = 0xb9, + + // Opcode added by BIP 342 (Tapscript) + OP_CHECKSIGADD = 0xba, + + OP_INVALIDOPCODE = 0xff, +} btc_enum_t; + +#endif \ No newline at end of file diff --git a/c/src/verifier/btc/btc_serialize.c b/c/src/verifier/btc/btc_serialize.c index 061b8066d..0f59d1867 100644 --- a/c/src/verifier/btc/btc_serialize.c +++ b/c/src/verifier/btc/btc_serialize.c @@ -35,6 +35,7 @@ bytes_t btc_block_get(bytes_t block, btc_block_field field) { default: return NULL_BYTES; } } + void btc_hash(bytes_t data, bytes32_t dst) { bytes32_t tmp; SHA256_CTX ctx; @@ -51,6 +52,7 @@ void btc_hash(bytes_t data, bytes32_t dst) { void rev_copy(uint8_t* dst, uint8_t* src) { for (int i = 0; i < 32; i++) dst[31 - i] = src[i]; } + void rev_copyl(uint8_t* dst, bytes_t src, int l) { if (src.len < (uint32_t) l) { memset(dst + src.len, 0, l - src.len); diff --git a/c/src/verifier/btc/btc_sign.c b/c/src/verifier/btc/btc_sign.c new file mode 100644 index 000000000..5e11d4c75 --- /dev/null +++ b/c/src/verifier/btc/btc_sign.c @@ -0,0 +1,111 @@ +#include "btc_sign.h" +#include "../../third-party/crypto/secp256k1.h" +#include "btc_serialize.h" +#include "btc_types.h" + +static void btc_sha256(uint8_t* data, uint32_t len, bytes32_t output) { + SHA256_CTX c; + sha256_Init(&c); + sha256_Update(&c, data, len); + sha256_Final(&c, output); +} + +void btc_dsha256(uint8_t* data, uint32_t len, bytes32_t output) { + bytes32_t tmp_hash; + btc_sha256(data, len, tmp_hash); + btc_sha256(tmp_hash, 32, output); +} + +// WARNING: You need to free tx_in pointer after calling this function! +void btc_sign_tx_in(const btc_tx_t* tx, const btc_tx_out_t* utxo, const bytes_t* priv_key, btc_tx_in_t* tx_in, uint8_t sighash) { + if (!tx_in || !priv_key) { + printf("ERROR: in btc_sign_tx_in: function arguments can not be NULL."); + return; + } + // TODO: Implement support for other sighashes + if (sighash != BTC_SIGHASH_ALL) { + printf("ERROR: in btc_sign_tx_in: Sighash not supported."); + return; + } + + btc_tx_t tmp_tx; + tmp_tx.version = tx->version; + tmp_tx.flag = 0; // TODO: Implement segwit support + tmp_tx.input_count = 1; + tmp_tx.output_count = tx->output_count; + tmp_tx.output = tx->output; + tmp_tx.lock_time = tx->lock_time; + + tx_in->script = utxo->script; // This should temporarily be the scriptPubKey of the output we want to redeem + btc_serialize_tx_in(tx_in, &tmp_tx.input); + + // prepare array for hashing + btc_serialize_tx(&tmp_tx, &(tmp_tx.all)); + bytes_t hash_input; + hash_input.len = tmp_tx.all.len + 4; + hash_input.data = malloc(hash_input.len * sizeof(uint8_t)); + + // TODO: Implement this in a more fficient way. There is no need to copy + // the whole tx just to add 4 bytes at the end of the stream + + // Copy serialized transaction + for (uint32_t i = 0; i < tmp_tx.all.len; i++) { + hash_input.data[i] = tmp_tx.all.data[i]; + } + // write sighash (4 bytes) at the end of the input + uint_to_le(&hash_input, tmp_tx.all.len, sighash); + + // Finally, sign transaction input + // -- Obtain DER signature + uint8_t sig[64]; + bytes_t der_sig; + der_sig.data = alloca(sizeof(uint8_t) * 75); + ecdsa_sign(&secp256k1, HASHER_SHA2D, (const uint8_t*) priv_key->data, hash_input.data, hash_input.len, sig, NULL, NULL); // TODO: check if it is really DER encoded or if aditional logic is necessary + der_sig.len = ecdsa_sig_to_der(sig, der_sig.data); + + // -- Extract public key out of the provided private key. This will be used to build the tx_in scriptSig + uint8_t pub_key[65]; + ecdsa_get_public_key65(&secp256k1, (const uint8_t*) priv_key->data, pub_key); + + // -- build scriptSig: SCRIPT_SIG_LEN|DER_LEN|DER_SIG|PUB_KEY_LEN|PUB_BEY + tx_in->script.len = 1 + der_sig.len + 1 + 1 + 65; // 1 byte DER_SIG_LEN + DER_SIG + 1 byte SIGHASH + 1 byte PUBKEY_LEN + PUBKEY + tx_in->script.len += get_compact_uint_size(tx_in->script.len); // Also account for the compact uint at the beginning of the byte stream + tx_in->script.data = malloc(sizeof(uint8_t) * tx_in->script.len); + + bytes_t* b = &tx_in->script; + uint32_t index = 0; + long_to_compact_uint(b, index, tx_in->script.len); // write scriptSig len field + index += get_compact_uint_size(tx_in->script.len); + long_to_compact_uint(b, index, der_sig.len); // write der_sig len field + index += 1; // it is safe to assume the previous field only has 1 byte in a correct execution. TODO: Return an error in case der_sig_len is not 1 byte long + // write der signature + uint32_t i = 0; + while (i < der_sig.len) { + b->data[index++] = der_sig.data[i++]; + } + b->data[index++] = sighash; // write sighash + b->data[index++] = 65; // write pubkey len + // write pubkey + i = 0; + while (i < 65) { + b->data[index++] = pub_key[i++]; + } + // signature is complete + + _free(tmp_tx.all.data); + _free(tmp_tx.input.data); + _free(tmp_tx.output.data); + _free(hash_input.data); +} + +void btc_sign_tx(bytes_t* raw_tx, const btc_tx_out_t* utxo_list, bytes_t* priv_key, bytes_t* dst_sig) { + UNUSED_VAR(raw_tx); + UNUSED_VAR(priv_key); + UNUSED_VAR(dst_sig); + UNUSED_VAR(utxo_list); + // for each input in a tx: + // -- for each pub_key (assume we only have one pub key for now): + // -- -- sig = btc_sign_tx_in() + // -- -- add_sig_to_tx_in() + return; +} \ No newline at end of file diff --git a/c/src/verifier/btc/btc_sign.h b/c/src/verifier/btc/btc_sign.h new file mode 100644 index 000000000..9543c0ee0 --- /dev/null +++ b/c/src/verifier/btc/btc_sign.h @@ -0,0 +1,14 @@ +#ifndef _BTC_SIGN_H +#define _BTC_SIGN_H + +#include "btc_types.h" + +#define BTC_SIGHASH_ALL 0x1 +#define BTC_SIGHASH_NONE 0x2 +#define BTC_SIGHASH_SINGLE 0x3 +#define BTC_SIGHASH_ANYONECANPAY 0x80 + +void create_raw_tx(btc_tx_in_t* tx_in, uint32_t tx_in_len, btc_tx_out_t* tx_out, uint32_t tx_out_len, uint32_t lock_time, bytes_t* dst_raw_tx); +void btc_sign_tx_in(const btc_tx_t* tx, const btc_tx_out_t* utxo, const bytes_t* priv_key, btc_tx_in_t* tx_in, uint8_t sighash); + +#endif \ No newline at end of file diff --git a/c/src/verifier/btc/btc_types.c b/c/src/verifier/btc/btc_types.c index c079c5631..3f7537e56 100644 --- a/c/src/verifier/btc/btc_types.c +++ b/c/src/verifier/btc/btc_types.c @@ -222,3 +222,68 @@ in3_ret_t btc_tx_id(btc_tx_t* tx, bytes32_t dst) { if (data.len > 1000) _free(data.data); return IN3_OK; } + +// creates a raw unsigned transaction +// TODO: implement better error handling +// TODO: Support witnesses +void create_raw_tx(btc_tx_in_t* tx_in, uint32_t tx_in_len, btc_tx_out_t* tx_out, uint32_t tx_out_len, uint32_t lock_time, bytes_t* dst_raw_tx) { + if (!tx_in || !tx_out || !dst_raw_tx || tx_in_len == 0 || tx_out_len == 0) { + // TODO: Implement better error handling + printf("ERROR: arguments for creating a btc transaction can not be null\n"); + return; + } + btc_tx_t tx; + tx.version = 1; + tx.flag = 0; + tx.input_count = tx_in_len; + tx.output_count = tx_out_len; + tx.lock_time = lock_time; + + // Get inputs + // -- serialize inputs + bytes_t* serialized_inputs = malloc(tx_in_len * sizeof(bytes_t)); + uint32_t raw_input_size = 0; + for (uint32_t i = 0; i < tx_in_len; i++) { + btc_serialize_tx_in(&tx_in[i], &serialized_inputs[i]); + raw_input_size += serialized_inputs[i].len; + } + // -- Copy raw inputs into tx + tx.input.data = malloc(raw_input_size); + tx.input.len = raw_input_size; + uint32_t prev_input_len = 0; + for (uint32_t i = 0; i < tx_in_len; i++) { + for (uint32_t j = 0; j < serialized_inputs[i].len; j++) { + tx.input.data[j + prev_input_len] = serialized_inputs[i].data[j]; + } + prev_input_len = serialized_inputs[i].len; + } + + // Get Outputs + // -- serialize outputs + bytes_t* serialized_outputs = malloc(tx_out_len * sizeof(bytes_t)); + uint32_t raw_output_size = 0; + for (uint32_t i = 0; i < tx_out_len; i++) { + btc_serialize_tx_out(&tx_out[i], &serialized_outputs[i]); + raw_output_size += serialized_outputs[i].len; + } + // -- Copy raw outputs into tx + tx.output.data = malloc(raw_output_size); + tx.output.len = raw_output_size; + uint32_t prev_output_len = 0; + for (uint32_t i = 0; i < tx_out_len; i++) { + for (uint32_t j = 0; j < serialized_outputs[i].len; j++) { + tx.output.data[j + prev_output_len] = serialized_outputs[i].data[j]; + } + prev_output_len = serialized_outputs[i].len; + } + + // free buffers + for (uint32_t i = 0; i < tx_in_len; i++) { + _free(serialized_inputs[i].data); + } + _free(serialized_inputs); + for (uint32_t i = 0; i < tx_out_len; i++) { + _free(serialized_outputs[i].data); + } + _free(serialized_outputs); +} \ No newline at end of file diff --git a/c/src/verifier/btc/btc_types.h b/c/src/verifier/btc/btc_types.h index 3a7822ff1..34cc70ad3 100644 --- a/c/src/verifier/btc/btc_types.h +++ b/c/src/verifier/btc/btc_types.h @@ -43,6 +43,8 @@ void btc_serialize_tx_out(btc_tx_out_t* tx_out, bytes_t* dst); uint32_t btc_vsize(btc_tx_t* tx); uint32_t btc_weight(btc_tx_t* tx); +void create_raw_tx(btc_tx_in_t* tx_in, uint32_t tx_in_len, btc_tx_out_t* tx_out, uint32_t tx_out_len, uint32_t lock_time, bytes_t* dst_raw_tx); + static inline bool btc_is_witness(bytes_t tx) { return tx.data[4] == 0 && tx.data[5] == 1; } From f3ba460b1dba46af325d44154f0ac07e14558f52 Mon Sep 17 00:00:00 2001 From: Leonardo Souza Date: Wed, 13 Oct 2021 16:12:17 +0200 Subject: [PATCH 080/101] Implement BTC transaction signer --- c/src/verifier/btc/btc_sign.c | 35 ++++++++++++++++++++++++++--------- c/src/verifier/btc/btc_sign.h | 1 + 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/c/src/verifier/btc/btc_sign.c b/c/src/verifier/btc/btc_sign.c index 5e11d4c75..c2900257b 100644 --- a/c/src/verifier/btc/btc_sign.c +++ b/c/src/verifier/btc/btc_sign.c @@ -16,7 +16,24 @@ void btc_dsha256(uint8_t* data, uint32_t len, bytes32_t output) { btc_sha256(tmp_hash, 32, output); } -// WARNING: You need to free tx_in pointer after calling this function! +static void add_input_to_tx(btc_tx_t* tx, btc_tx_in_t* tx_in) { + tx->input_count++; + + // check size of serialized tx input + bytes_t raw_tx_in; + btc_serialize_tx_in(tx_in, &raw_tx_in); + + uint32_t old_len = tx->input.len; + tx->input.len += raw_tx_in.len; + tx->input.data = realloc(tx->input.data, tx->input.len * sizeof(*tx->input.data)); // TODO: This is inneficient when we have lots of inputs to deal with. Implement a more efficient solution. + + // Add raw tx_in to tx data + for (uint32_t i = 0; i < raw_tx_in.len; i++) { + tx->input.data[old_len + i] = raw_tx_in.data[i]; + } +} + +// WARNING: You need to free tx_in->script.data after calling this function! void btc_sign_tx_in(const btc_tx_t* tx, const btc_tx_out_t* utxo, const bytes_t* priv_key, btc_tx_in_t* tx_in, uint8_t sighash) { if (!tx_in || !priv_key) { printf("ERROR: in btc_sign_tx_in: function arguments can not be NULL."); @@ -98,14 +115,14 @@ void btc_sign_tx_in(const btc_tx_t* tx, const btc_tx_out_t* utxo, const bytes_t* _free(hash_input.data); } -void btc_sign_tx(bytes_t* raw_tx, const btc_tx_out_t* utxo_list, bytes_t* priv_key, bytes_t* dst_sig) { - UNUSED_VAR(raw_tx); - UNUSED_VAR(priv_key); - UNUSED_VAR(dst_sig); - UNUSED_VAR(utxo_list); +void btc_sign_tx(btc_tx_t* tx, const btc_tx_out_t* selected_utxo_list, uint32_t utxo_list_len, bytes_t* priv_key) { // for each input in a tx: - // -- for each pub_key (assume we only have one pub key for now): - // -- -- sig = btc_sign_tx_in() - // -- -- add_sig_to_tx_in() + for (uint32_t i = 0; i < utxo_list_len; i++) { + // -- for each pub_key (assume we only have one pub key for now): + btc_tx_in_t tx_in; + btc_sign_tx_in(tx, &selected_utxo_list[i], priv_key, &tx_in, BTC_SIGHASH_ALL); + add_input_to_tx(tx, &tx_in); + _free(tx_in.script.data); + } return; } \ No newline at end of file diff --git a/c/src/verifier/btc/btc_sign.h b/c/src/verifier/btc/btc_sign.h index 9543c0ee0..2d7b76343 100644 --- a/c/src/verifier/btc/btc_sign.h +++ b/c/src/verifier/btc/btc_sign.h @@ -10,5 +10,6 @@ void create_raw_tx(btc_tx_in_t* tx_in, uint32_t tx_in_len, btc_tx_out_t* tx_out, uint32_t tx_out_len, uint32_t lock_time, bytes_t* dst_raw_tx); void btc_sign_tx_in(const btc_tx_t* tx, const btc_tx_out_t* utxo, const bytes_t* priv_key, btc_tx_in_t* tx_in, uint8_t sighash); +void btc_sign_tx(btc_tx_t* tx, const btc_tx_out_t* selected_utxo_list, uint32_t utxo_list_len, bytes_t* priv_key); #endif \ No newline at end of file From 00fa6f1bb53d1fdb33909aea03552352e251e2ab Mon Sep 17 00:00:00 2001 From: Leonardo Souza Date: Mon, 25 Oct 2021 19:35:37 +0200 Subject: [PATCH 081/101] Fix series of errors in btc signer --- c/src/verifier/btc/btc_sign.c | 79 +++++++++++++++------------------- c/src/verifier/btc/btc_sign.h | 2 +- c/src/verifier/btc/btc_types.c | 58 +++++++++++++++++++++++-- c/src/verifier/btc/btc_types.h | 9 +++- 4 files changed, 98 insertions(+), 50 deletions(-) diff --git a/c/src/verifier/btc/btc_sign.c b/c/src/verifier/btc/btc_sign.c index c2900257b..9b4cd89ce 100644 --- a/c/src/verifier/btc/btc_sign.c +++ b/c/src/verifier/btc/btc_sign.c @@ -3,40 +3,27 @@ #include "btc_serialize.h" #include "btc_types.h" -static void btc_sha256(uint8_t* data, uint32_t len, bytes32_t output) { - SHA256_CTX c; - sha256_Init(&c); - sha256_Update(&c, data, len); - sha256_Final(&c, output); -} - -void btc_dsha256(uint8_t* data, uint32_t len, bytes32_t output) { - bytes32_t tmp_hash; - btc_sha256(data, len, tmp_hash); - btc_sha256(tmp_hash, 32, output); -} - -static void add_input_to_tx(btc_tx_t* tx, btc_tx_in_t* tx_in) { - tx->input_count++; - - // check size of serialized tx input - bytes_t raw_tx_in; - btc_serialize_tx_in(tx_in, &raw_tx_in); - - uint32_t old_len = tx->input.len; - tx->input.len += raw_tx_in.len; - tx->input.data = realloc(tx->input.data, tx->input.len * sizeof(*tx->input.data)); // TODO: This is inneficient when we have lots of inputs to deal with. Implement a more efficient solution. - - // Add raw tx_in to tx data - for (uint32_t i = 0; i < raw_tx_in.len; i++) { - tx->input.data[old_len + i] = raw_tx_in.data[i]; +// Fill tx_in fields, preparing the input for signing +// WARNING: You need to free tx_in->prev_tx_hash after calling this function +static void init_tx_in(const btc_utxo_t* utxo, btc_tx_in_t* tx_in) { + if (!utxo || !tx_in) { + // TODO: Implement better error treatment + printf("ERROR: in init_tx_in: function arguments can not be null!\n"); + return; } + tx_in->prev_tx_index = utxo->tx_index; + tx_in->prev_tx_hash = malloc(32 * sizeof(uint8_t)); + memcpy(tx_in->prev_tx_hash, utxo->tx_hash, 32); + tx_in->script.len = 0; + tx_in->script.data = NULL; + tx_in->sequence = 0xffffffff; } // WARNING: You need to free tx_in->script.data after calling this function! void btc_sign_tx_in(const btc_tx_t* tx, const btc_tx_out_t* utxo, const bytes_t* priv_key, btc_tx_in_t* tx_in, uint8_t sighash) { if (!tx_in || !priv_key) { - printf("ERROR: in btc_sign_tx_in: function arguments can not be NULL."); + // TODO: Implement better error handling + printf("ERROR: in btc_sign_tx_in: function arguments cannot be NULL."); return; } // TODO: Implement support for other sighashes @@ -46,13 +33,17 @@ void btc_sign_tx_in(const btc_tx_t* tx, const btc_tx_out_t* utxo, const bytes_t* } btc_tx_t tmp_tx; - tmp_tx.version = tx->version; - tmp_tx.flag = 0; // TODO: Implement segwit support - tmp_tx.input_count = 1; - tmp_tx.output_count = tx->output_count; - tmp_tx.output = tx->output; - tmp_tx.lock_time = tx->lock_time; - + tmp_tx.version = tx->version; + tmp_tx.flag = 0; // TODO: Implement segwit support + tmp_tx.input_count = 1; // TODO: support more than one input + tmp_tx.output_count = tx->output_count; + tmp_tx.output.len = tx->output.len; + tmp_tx.output.data = alloca(sizeof(uint8_t) * tmp_tx.output.len); + tmp_tx.witnesses.len = 0; + for (uint32_t i = 0; i < tmp_tx.output.len; i++) tmp_tx.output.data[i] = tx->output.data[i]; + tmp_tx.lock_time = tx->lock_time; + + // TODO: This should probably be set before calling the signer function. If this is done outside this function, then the utxo is probably not needed. tx_in->script = utxo->script; // This should temporarily be the scriptPubKey of the output we want to redeem btc_serialize_tx_in(tx_in, &tmp_tx.input); @@ -62,9 +53,8 @@ void btc_sign_tx_in(const btc_tx_t* tx, const btc_tx_out_t* utxo, const bytes_t* hash_input.len = tmp_tx.all.len + 4; hash_input.data = malloc(hash_input.len * sizeof(uint8_t)); - // TODO: Implement this in a more fficient way. There is no need to copy + // TODO: Implement this in a more efficient way. There is no need to copy // the whole tx just to add 4 bytes at the end of the stream - // Copy serialized transaction for (uint32_t i = 0; i < tmp_tx.all.len; i++) { hash_input.data[i] = tmp_tx.all.data[i]; @@ -74,10 +64,10 @@ void btc_sign_tx_in(const btc_tx_t* tx, const btc_tx_out_t* utxo, const bytes_t* // Finally, sign transaction input // -- Obtain DER signature - uint8_t sig[64]; + uint8_t sig[65]; bytes_t der_sig; der_sig.data = alloca(sizeof(uint8_t) * 75); - ecdsa_sign(&secp256k1, HASHER_SHA2D, (const uint8_t*) priv_key->data, hash_input.data, hash_input.len, sig, NULL, NULL); // TODO: check if it is really DER encoded or if aditional logic is necessary + ecdsa_sign(&secp256k1, HASHER_SHA2D, priv_key->data, hash_input.data, hash_input.len, sig, sig + 64, NULL); der_sig.len = ecdsa_sig_to_der(sig, der_sig.data); // -- Extract public key out of the provided private key. This will be used to build the tx_in scriptSig @@ -95,7 +85,7 @@ void btc_sign_tx_in(const btc_tx_t* tx, const btc_tx_out_t* utxo, const bytes_t* index += get_compact_uint_size(tx_in->script.len); long_to_compact_uint(b, index, der_sig.len); // write der_sig len field index += 1; // it is safe to assume the previous field only has 1 byte in a correct execution. TODO: Return an error in case der_sig_len is not 1 byte long - // write der signature + // write DER signature uint32_t i = 0; while (i < der_sig.len) { b->data[index++] = der_sig.data[i++]; @@ -107,22 +97,23 @@ void btc_sign_tx_in(const btc_tx_t* tx, const btc_tx_out_t* utxo, const bytes_t* while (i < 65) { b->data[index++] = pub_key[i++]; } - // signature is complete + // signature is complete _free(tmp_tx.all.data); _free(tmp_tx.input.data); - _free(tmp_tx.output.data); _free(hash_input.data); } -void btc_sign_tx(btc_tx_t* tx, const btc_tx_out_t* selected_utxo_list, uint32_t utxo_list_len, bytes_t* priv_key) { +void btc_sign_tx(btc_tx_t* tx, const btc_utxo_t* selected_utxo_list, uint32_t utxo_list_len, bytes_t* priv_key) { // for each input in a tx: for (uint32_t i = 0; i < utxo_list_len; i++) { // -- for each pub_key (assume we only have one pub key for now): btc_tx_in_t tx_in; - btc_sign_tx_in(tx, &selected_utxo_list[i], priv_key, &tx_in, BTC_SIGHASH_ALL); + init_tx_in(&selected_utxo_list[i], &tx_in); + btc_sign_tx_in(tx, &selected_utxo_list[i].tx_out, priv_key, &tx_in, BTC_SIGHASH_ALL); add_input_to_tx(tx, &tx_in); _free(tx_in.script.data); + _free(tx_in.prev_tx_hash); } return; } \ No newline at end of file diff --git a/c/src/verifier/btc/btc_sign.h b/c/src/verifier/btc/btc_sign.h index 2d7b76343..9ac2c8d81 100644 --- a/c/src/verifier/btc/btc_sign.h +++ b/c/src/verifier/btc/btc_sign.h @@ -10,6 +10,6 @@ void create_raw_tx(btc_tx_in_t* tx_in, uint32_t tx_in_len, btc_tx_out_t* tx_out, uint32_t tx_out_len, uint32_t lock_time, bytes_t* dst_raw_tx); void btc_sign_tx_in(const btc_tx_t* tx, const btc_tx_out_t* utxo, const bytes_t* priv_key, btc_tx_in_t* tx_in, uint8_t sighash); -void btc_sign_tx(btc_tx_t* tx, const btc_tx_out_t* selected_utxo_list, uint32_t utxo_list_len, bytes_t* priv_key); +void btc_sign_tx(btc_tx_t* tx, const btc_utxo_t* selected_utxo_list, uint32_t utxo_list_len, bytes_t* priv_key); #endif \ No newline at end of file diff --git a/c/src/verifier/btc/btc_types.c b/c/src/verifier/btc/btc_types.c index 3f7537e56..41da29f6e 100644 --- a/c/src/verifier/btc/btc_types.c +++ b/c/src/verifier/btc/btc_types.c @@ -13,6 +13,11 @@ // Output fixed size values #define BTC_TX_OUT_VALUE_SIZE_BYTES 8 +typedef enum btc_tx_field { + INPUT, + OUTPUT +} btc_tx_field_t; + uint8_t* btc_parse_tx_in(uint8_t* data, btc_tx_in_t* dst, uint8_t* limit) { uint64_t len; dst->prev_tx_hash = data; @@ -24,7 +29,7 @@ uint8_t* btc_parse_tx_in(uint8_t* data, btc_tx_in_t* dst, uint8_t* limit) { return dst->script.data + dst->script.len + 4; } -// WARNING: You need to free 'dst' pointer after calling this function +// WARNING: You need to free dst.data after calling this function // TODO: Implement support for "Coinbase" inputs // TODO: Handle null arguments // TODO: Handle max script len = 10000 bytes @@ -45,7 +50,7 @@ void btc_serialize_tx_in(btc_tx_in_t* tx_in, bytes_t* dst) { if (!tx_in->prev_tx_hash) return; uint32_t index = 0; for (uint32_t i = 0; i < 32; i++) { - dst->data[index++] = tx_in->prev_tx_hash[i]; + dst->data[index++] = tx_in->prev_tx_hash[31 - i]; } uint_to_le(dst, index, tx_in->prev_tx_index); index += 4; @@ -149,7 +154,7 @@ in3_ret_t btc_serialize_tx(btc_tx_t* tx, bytes_t* dst) { tx->input.len + get_compact_uint_size((uint64_t) tx->output_count) + tx->output.len + - tx->witnesses.len + + (tx->flag ? tx->witnesses.len : 0) + BTC_TX_LOCKTIME_SIZE_BYTES); dst->data = malloc(tx_size * sizeof(*dst->data)); @@ -188,7 +193,6 @@ in3_ret_t btc_serialize_tx(btc_tx_t* tx, bytes_t* dst) { } } // locktime - //uint_to_le(dst, index, tx->lock_time); dst->data[index + 3] = ((tx->lock_time >> 24) & 0xff); dst->data[index + 2] = ((tx->lock_time >> 16) & 0xff); dst->data[index + 1] = ((tx->lock_time >> 8) & 0xff); @@ -286,4 +290,50 @@ void create_raw_tx(btc_tx_in_t* tx_in, uint32_t tx_in_len, btc_tx_out_t* tx_out, _free(serialized_outputs[i].data); } _free(serialized_outputs); +} + +void add_to_tx(btc_tx_t* tx, void* src, btc_tx_field_t field_type) { + if (!tx || !src) { + printf("ERROR: in add_to_tx: Function arguments cannot be null!\n"); + return; + } + + bytes_t raw_src, *dst; + uint32_t old_len; + + switch (field_type) { + case INPUT: + btc_serialize_tx_in((btc_tx_in_t*) src, &raw_src); + old_len = tx->input.len; + dst = &tx->input; + tx->input_count++; + break; + case OUTPUT: + btc_serialize_tx_out((btc_tx_out_t*) src, &raw_src); + old_len = tx->output.len; + dst = &tx->output; + tx->output_count++; + break; + default: + // TODO: Implement better error handling + printf("Unrecognized transaction field code. No action was performed."); + } + + dst->len += raw_src.len; + size_t mem_size = dst->len * sizeof(*dst->data); + dst->data = (!dst->data) ? malloc(mem_size) : realloc(dst->data, mem_size); + + // Add bytes to tx field + for (uint32_t i = 0; i < raw_src.len; i++) { + dst->data[old_len + i] = raw_src.data[i]; + } + return; +} + +void add_input_to_tx(btc_tx_t* tx, btc_tx_in_t* tx_in) { + add_to_tx(tx, tx_in, INPUT); +} + +void add_output_to_tx(btc_tx_t* tx, btc_tx_out_t* tx_out) { + add_to_tx(tx, tx_out, OUTPUT); } \ No newline at end of file diff --git a/c/src/verifier/btc/btc_types.h b/c/src/verifier/btc/btc_types.h index 34cc70ad3..06c022778 100644 --- a/c/src/verifier/btc/btc_types.h +++ b/c/src/verifier/btc/btc_types.h @@ -30,6 +30,12 @@ typedef struct btc_tx_out { bytes_t script; } btc_tx_out_t; +typedef struct btc_utxo { + uint8_t* tx_hash; + uint32_t tx_index; + btc_tx_out_t tx_out; +} btc_utxo_t; + in3_ret_t btc_parse_tx(bytes_t tx, btc_tx_t* dst); in3_ret_t btc_serialize_tx(btc_tx_t* tx, bytes_t* dst); in3_ret_t btc_tx_id(btc_tx_t* tx, bytes32_t dst); @@ -43,7 +49,8 @@ void btc_serialize_tx_out(btc_tx_out_t* tx_out, bytes_t* dst); uint32_t btc_vsize(btc_tx_t* tx); uint32_t btc_weight(btc_tx_t* tx); -void create_raw_tx(btc_tx_in_t* tx_in, uint32_t tx_in_len, btc_tx_out_t* tx_out, uint32_t tx_out_len, uint32_t lock_time, bytes_t* dst_raw_tx); +void add_input_to_tx(btc_tx_t* tx, btc_tx_in_t* tx_in); +void add_output_to_tx(btc_tx_t* tx, btc_tx_out_t* tx_out); static inline bool btc_is_witness(bytes_t tx) { return tx.data[4] == 0 && tx.data[5] == 1; From de385df16f0a8e1585c65c292834122a7aed57b4 Mon Sep 17 00:00:00 2001 From: Leonardo Souza Date: Wed, 27 Oct 2021 13:23:55 +0200 Subject: [PATCH 082/101] Fix tx signer generating invalid transaction --- c/src/verifier/btc/btc_sign.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/c/src/verifier/btc/btc_sign.c b/c/src/verifier/btc/btc_sign.c index 9b4cd89ce..03efa229e 100644 --- a/c/src/verifier/btc/btc_sign.c +++ b/c/src/verifier/btc/btc_sign.c @@ -53,8 +53,9 @@ void btc_sign_tx_in(const btc_tx_t* tx, const btc_tx_out_t* utxo, const bytes_t* hash_input.len = tmp_tx.all.len + 4; hash_input.data = malloc(hash_input.len * sizeof(uint8_t)); - // TODO: Implement this in a more efficient way. There is no need to copy + // TODO: Implement this in a more efficient way. Right now we copy // the whole tx just to add 4 bytes at the end of the stream + // Copy serialized transaction for (uint32_t i = 0; i < tmp_tx.all.len; i++) { hash_input.data[i] = tmp_tx.all.data[i]; @@ -66,32 +67,32 @@ void btc_sign_tx_in(const btc_tx_t* tx, const btc_tx_out_t* utxo, const bytes_t* // -- Obtain DER signature uint8_t sig[65]; bytes_t der_sig; + der_sig.data = alloca(sizeof(uint8_t) * 75); ecdsa_sign(&secp256k1, HASHER_SHA2D, priv_key->data, hash_input.data, hash_input.len, sig, sig + 64, NULL); - der_sig.len = ecdsa_sig_to_der(sig, der_sig.data); + der_sig.len = ecdsa_sig_to_der(sig, der_sig.data); + der_sig.data[der_sig.len++] = sig[64]; // append verification byte to end of DER signature // -- Extract public key out of the provided private key. This will be used to build the tx_in scriptSig uint8_t pub_key[65]; ecdsa_get_public_key65(&secp256k1, (const uint8_t*) priv_key->data, pub_key); - // -- build scriptSig: SCRIPT_SIG_LEN|DER_LEN|DER_SIG|PUB_KEY_LEN|PUB_BEY - tx_in->script.len = 1 + der_sig.len + 1 + 1 + 65; // 1 byte DER_SIG_LEN + DER_SIG + 1 byte SIGHASH + 1 byte PUBKEY_LEN + PUBKEY - tx_in->script.len += get_compact_uint_size(tx_in->script.len); // Also account for the compact uint at the beginning of the byte stream - tx_in->script.data = malloc(sizeof(uint8_t) * tx_in->script.len); + // -- build scriptSig: DER_LEN|DER_SIG|PUB_KEY_LEN|PUB_BEY + uint32_t scriptsig_len = der_sig.len + 1 + 65; // DER_SIG + 1 byte PUBKEY_LEN + PUBKEY + tx_in->script.len = 1 + scriptsig_len; // Also account for 1 byte DER_SIG_LEN + tx_in->script.data = malloc(sizeof(uint8_t) * tx_in->script.len); bytes_t* b = &tx_in->script; uint32_t index = 0; - long_to_compact_uint(b, index, tx_in->script.len); // write scriptSig len field - index += get_compact_uint_size(tx_in->script.len); + long_to_compact_uint(b, index, der_sig.len); // write der_sig len field - index += 1; // it is safe to assume the previous field only has 1 byte in a correct execution. TODO: Return an error in case der_sig_len is not 1 byte long - // write DER signature + index += 1; // it is safe to assume the previous field only has 1 byte in a correct execution. + // write der signature uint32_t i = 0; while (i < der_sig.len) { b->data[index++] = der_sig.data[i++]; } - b->data[index++] = sighash; // write sighash - b->data[index++] = 65; // write pubkey len + b->data[index++] = 65; // write pubkey len // write pubkey i = 0; while (i < 65) { @@ -108,6 +109,7 @@ void btc_sign_tx(btc_tx_t* tx, const btc_utxo_t* selected_utxo_list, uint32_t ut // for each input in a tx: for (uint32_t i = 0; i < utxo_list_len; i++) { // -- for each pub_key (assume we only have one pub key for now): + // TODO: Allow setting a specific pub_key for each input btc_tx_in_t tx_in; init_tx_in(&selected_utxo_list[i], &tx_in); btc_sign_tx_in(tx, &selected_utxo_list[i].tx_out, priv_key, &tx_in, BTC_SIGHASH_ALL); From 94e9fe8b02e7f30336b33db01594454015b2cea3 Mon Sep 17 00:00:00 2001 From: leonardotc Date: Mon, 4 Oct 2021 16:51:42 +0200 Subject: [PATCH 083/101] Change java signer --- dotnet/In3/Crypto/SignatureType.cs | 5 + java/build.gradle | 2 +- java/settings.gradle | 1 + java/src/CMakeLists.txt | 1 + java/src/in3/IN3.java | 22 ++-- java/src/in3/eth1/API.java | 72 ++++++------ java/src/in3/eth1/SimpleWallet.java | 29 ++--- java/src/in3/utils/PayloadType.java | 27 +++++ java/src/in3/utils/Signature.java | 2 + java/src/in3/utils/SignatureType.java | 32 ++++- java/src/in3/utils/Signer.java | 24 ++-- java/src/in3_jni.c | 141 +++++++++++++++++------ java/src/in3_jni.h | 12 +- java/test/in3/eth1/SimpleWalletTest.java | 24 ++-- 14 files changed, 257 insertions(+), 137 deletions(-) create mode 100644 java/settings.gradle create mode 100644 java/src/in3/utils/PayloadType.java diff --git a/dotnet/In3/Crypto/SignatureType.cs b/dotnet/In3/Crypto/SignatureType.cs index df2e21261..6cf6db719 100644 --- a/dotnet/In3/Crypto/SignatureType.cs +++ b/dotnet/In3/Crypto/SignatureType.cs @@ -23,5 +23,10 @@ public class SignatureType /// For data that was hashed and then signed. /// public static SignatureType Hash { get { return new SignatureType("hash"); } } + + /// + /// For data hashed twice with sha256 and signed. + /// + public static SignatureType Btc { get { return new SignatureType("btc"); } } } } \ No newline at end of file diff --git a/java/build.gradle b/java/build.gradle index 7f0bb9d69..d902c6ba2 100644 --- a/java/build.gradle +++ b/java/build.gradle @@ -32,7 +32,7 @@ task copyJarToBindings(type: Copy) { sourceSets { main { java { - srcDirs = [jarOutputFolder] + srcDirs = [jarOutputFolder] // srcDirs = ['src'] Needed to run the project as a standalone gradle project } resources { srcDirs = [jarOutputFolder] diff --git a/java/settings.gradle b/java/settings.gradle new file mode 100644 index 000000000..b8d704ce5 --- /dev/null +++ b/java/settings.gradle @@ -0,0 +1 @@ +rootProject.name = "in3" \ No newline at end of file diff --git a/java/src/CMakeLists.txt b/java/src/CMakeLists.txt index cd4579b55..9bad8b6ef 100644 --- a/java/src/CMakeLists.txt +++ b/java/src/CMakeLists.txt @@ -88,6 +88,7 @@ IF (NOT DEFINED ANDROID_ABI) in3/utils/Crypto.java in3/utils/JSON.java in3/utils/Converter.java + in3/utils/PayloadType.java in3/utils/Signature.java in3/utils/SignatureType.java in3/utils/Signer.java diff --git a/java/src/in3/IN3.java b/java/src/in3/IN3.java index 3bf0e9b43..080a54f0b 100644 --- a/java/src/in3/IN3.java +++ b/java/src/in3/IN3.java @@ -35,8 +35,11 @@ package in3; import in3.config.ClientConfiguration; +import in3.eth1.SimpleWallet; import in3.utils.Crypto; import in3.utils.JSON; +import in3.utils.PayloadType; +import in3.utils.SignatureType; import in3.utils.Signer; import in3.utils.StorageProvider; import in3.utils.TransportException; @@ -380,16 +383,13 @@ protected Object[] handleEns(Object[] params) { // Test it public static void main(String[] args) { - Object[] params = new Object[args.length - 1]; - for (int i = 1; i < args.length; i++) - params[i - 1] = args[i]; - - // create client - IN3 in3 = IN3.forChain(Chain.MAINNET); - // set cache in tempfolder - in3.setStorageProvider(new in3.utils.TempStorageProvider()); - - // execute the command - System.out.println(in3.sendRPC(args[0], params)); + IN3 in3 = new IN3(Chain.GOERLI); + SimpleWallet wallet = new SimpleWallet(); + String pk = "0x889dbed9450f7a4b68e0732ccb7cd016dab158e6946d16158f2736fda1143ca6"; + String address = wallet.addRawKey(pk); + byte[] res = wallet.sign("1e194c68360307cfb715bf17878791ad1ced8da7d2e5f42b691074c577f41eac", + address, SignatureType.eth_sign, PayloadType.PL_SIGN_ETHTX, null); + + System.out.println(res); } } \ No newline at end of file diff --git a/java/src/in3/eth1/API.java b/java/src/in3/eth1/API.java index 17d8eba79..78b317bf1 100644 --- a/java/src/in3/eth1/API.java +++ b/java/src/in3/eth1/API.java @@ -94,30 +94,29 @@ public API(IN3 in3) { * the lastest block. */ public Block getBlockByNumber(long block, /** - < the Blocknumber + * < the Blocknumber */ boolean includeTransactions /** * < if true all Transactions will be includes, if not only the * transactionhashes */ ) { - return Block.asBlock(in3.sendRPCasObject(GET_BLOCK_BY_NUMBER, - new Object[] {getBlockString(block), includeTransactions})); + return Block + .asBlock(in3.sendRPCasObject(GET_BLOCK_BY_NUMBER, new Object[] {getBlockString(block), includeTransactions})); } /** * Returns information about a block by hash. */ public Block getBlockByHash(String blockHash, /** - < the Blocknumber + * < the Blocknumber */ boolean includeTransactions /** * < if true all Transactions will be includes, if not only the * transactionhashes */ ) { - return Block - .asBlock(in3.sendRPCasObject(BLOCK_BY_HASH, new Object[] {blockHash, includeTransactions})); + return Block.asBlock(in3.sendRPCasObject(BLOCK_BY_HASH, new Object[] {blockHash, includeTransactions})); } /** @@ -149,14 +148,14 @@ public String getChainId() { * will be returned, if not an array of objects will be the result. */ public Object call(TransactionRequest request, /** - < the transaction to call. + * < the transaction to call. */ long block /** - < the Block used to for the state. + * < the Block used to for the state. */ ) { - return request.getResult((String) in3.sendRPCasObject(CALL, - new Object[] {request.getTransactionJson(), getBlockString(block)})); + return request.getResult( + (String) in3.sendRPCasObject(CALL, new Object[] {request.getTransactionJson(), getBlockString(block)})); } /** @@ -166,22 +165,21 @@ public Object call(TransactionRequest request, /** * @return the gas required to call the function. */ public long estimateGas(TransactionRequest request, /** - < the transaction to call. + * < the transaction to call. */ long block /** - < the Block used to for the state. + * < the Block used to for the state. */ ) { - return JSON.asLong(in3.sendRPCasObject(ESTIMATE_GAS, - new Object[] {request.getTransactionJson(), getBlockString(block)})); + return JSON.asLong( + in3.sendRPCasObject(ESTIMATE_GAS, new Object[] {request.getTransactionJson(), getBlockString(block)})); } /** * Returns the balance of the account of given address in wei. */ public BigInteger getBalance(String address, long block) { - return JSON - .asBigInteger(in3.sendRPCasObject(GET_BALANCE, new Object[] {address, getBlockString(block)})); + return JSON.asBigInteger(in3.sendRPCasObject(GET_BALANCE, new Object[] {address, getBlockString(block)})); } /** @@ -195,8 +193,8 @@ public String getCode(String address, long block) { * Returns the value from a storage position at a given address. */ public String getStorageAt(String address, BigInteger position, long block) { - return JSON.asString(in3.sendRPCasObject(GET_STORAGE_AT, - new Object[] {address, JSON.asString(position), getBlockString(block)})); + return JSON.asString( + in3.sendRPCasObject(GET_STORAGE_AT, new Object[] {address, JSON.asString(position), getBlockString(block)})); } /** @@ -212,8 +210,8 @@ public long getBlockTransactionCountByHash(String blockHash) { * block number. */ public long getBlockTransactionCountByNumber(long block) { - return JSON.asLong( - in3.sendRPCasObject(GET_BLOCK_TRANSACTION_COUNT_BY_NUMBER, new Object[] {getBlockString(block)})); + return JSON + .asLong(in3.sendRPCasObject(GET_BLOCK_TRANSACTION_COUNT_BY_NUMBER, new Object[] {getBlockString(block)})); } /** @@ -253,8 +251,8 @@ public Log[] getLogs(LogFilter filter) { * position. */ public Transaction getTransactionByBlockHashAndIndex(String blockHash, int index) { - return Transaction.asTransaction(in3.sendRPCasObject(GET_TRANSACTION_BY_BLOCK_HASH_AND_INDEX, - new Object[] {blockHash, JSON.asString(index)})); + return Transaction.asTransaction( + in3.sendRPCasObject(GET_TRANSACTION_BY_BLOCK_HASH_AND_INDEX, new Object[] {blockHash, JSON.asString(index)})); } /** @@ -270,24 +268,23 @@ public Transaction getTransactionByBlockNumberAndIndex(long block, int index) { * Returns the information about a transaction requested by transaction hash. */ public Transaction getTransactionByHash(String transactionHash) { - return Transaction - .asTransaction(in3.sendRPCasObject(GET_TRANSACTION_BY_HASH, new Object[] {transactionHash})); + return Transaction.asTransaction(in3.sendRPCasObject(GET_TRANSACTION_BY_HASH, new Object[] {transactionHash})); } /** * Returns the number of transactions sent from an address. */ public BigInteger getTransactionCount(String address, long block) { - return JSON.asBigInteger( - in3.sendRPCasObject(GET_TRANSACTION_COUNT, new Object[] {address, getBlockString(block)})); + return JSON + .asBigInteger(in3.sendRPCasObject(GET_TRANSACTION_COUNT, new Object[] {address, getBlockString(block)})); } /** * Returns the number of transactions sent from an address. */ public TransactionReceipt getTransactionReceipt(String transactionHash) { - return TransactionReceipt.asTransactionReceipt( - in3.sendRPCasObject(GET_TRANSACTION_RECEIPT, new Object[] {transactionHash})); + return TransactionReceipt + .asTransactionReceipt(in3.sendRPCasObject(GET_TRANSACTION_RECEIPT, new Object[] {transactionHash})); } /** @@ -312,8 +309,7 @@ public long getUncleCountByBlockHash(String block) { * hash. */ public long getUncleCountByBlockNumber(long block) { - return JSON - .asLong(in3.sendRPCasObject(GET_UNCLE_COUNT_BY_BLOCK_NUMBER, new Object[] {getBlockString(block)})); + return JSON.asLong(in3.sendRPCasObject(GET_UNCLE_COUNT_BY_BLOCK_NUMBER, new Object[] {getBlockString(block)})); } /** @@ -360,12 +356,11 @@ public String sendRawTransaction(String data) { } /** - * encodes the arguments as described in the method signature using ABI-Encoding. + * encodes the arguments as described in the method signature using + * ABI-Encoding. */ public String abiEncode(String signature, String[] params) { - Object rawResult = in3.sendRPCasObject(ABI_ENCODE, new Object[] { - signature, - params}); + Object rawResult = in3.sendRPCasObject(ABI_ENCODE, new Object[] {signature, params}); return JSON.asString(rawResult); } @@ -385,7 +380,8 @@ public String checksumAddress(String address) { } /** - * converts the given address to a checksum address. Second parameter includes the chainId. + * converts the given address to a checksum address. Second parameter includes + * the chainId. */ public String checksumAddress(String address, Boolean useChainId) { return JSON.asString(in3.sendRPCasObject(CHECKSUM_ADDRESS, new Object[] {address, useChainId})); @@ -399,7 +395,8 @@ public String ens(String name) { } /** - * resolve ens-name. Second parameter especifies if it is an address, owner, resolver or hash. + * resolve ens-name. Second parameter especifies if it is an address, owner, + * resolver or hash. */ public String ens(String name, ENSMethod type) { return JSON.asString(in3.sendRPCasObject(ENS, new Object[] {name, type}, false)); @@ -415,9 +412,6 @@ public String sendTransaction(TransactionRequest tx) { throw new RuntimeException("No Signer set. This is needed in order to sign transaction."); if (tx.getFrom() == null) throw new RuntimeException("No from address set"); - if (!signer.canSign(tx.getFrom())) - throw new RuntimeException("The from address is not supported by the signer"); - tx = signer.prepareTransaction(in3, tx); return JSON.asString(in3.sendRPCasObject(SEND_TRANSACTION, new Object[] {tx.getTransactionJson()})); } diff --git a/java/src/in3/eth1/SimpleWallet.java b/java/src/in3/eth1/SimpleWallet.java index 650b25bb7..80c4d0d55 100644 --- a/java/src/in3/eth1/SimpleWallet.java +++ b/java/src/in3/eth1/SimpleWallet.java @@ -36,14 +36,14 @@ import in3.IN3; import in3.Loader; -import in3.utils.Signer; +import in3.utils.*; import java.util.*; /** * a simple Implementation for holding private keys to sing data or * transactions. */ -public class SimpleWallet implements Signer { +public class SimpleWallet extends Signer { static { Loader.loadLibrary(); @@ -52,6 +52,14 @@ public class SimpleWallet implements Signer { // ke for holding the map Map privateKeys = new HashMap(); + /** + * returns the accounts supported by the wallet. + */ + @Override + public String[] getAccounts() { + return privateKeys.keySet().toArray(new String[0]); + } + /** * adds a key to the wallet and returns its public address. */ @@ -83,24 +91,11 @@ public TransactionRequest prepareTransaction(IN3 in3, TransactionRequest tx) { return tx; } - /** - * returns true if the account is supported (or unlocked) - */ - public boolean canSign(String address) { - return privateKeys.containsKey(address.toLowerCase()); - } - /** * signing of the raw data. */ - public String sign(String data, String address) { + public byte[] sign(String data, String address, SignatureType signatureType, PayloadType j, JSON payload) { String key = privateKeys.get(address.toLowerCase()); - return signData(key, data); + return signData(key, data, signatureType); } - - private static native String getAddressFromKey(String key); - - private static native String signData(String key, String data); - - private static native String decodeKeystore(String keystore, String passwd); } diff --git a/java/src/in3/utils/PayloadType.java b/java/src/in3/utils/PayloadType.java new file mode 100644 index 000000000..7d31c5a67 --- /dev/null +++ b/java/src/in3/utils/PayloadType.java @@ -0,0 +1,27 @@ +package in3.utils; + +/* + * Enum that represents a type of payload for the signer + */ +public enum PayloadType { + PL_SIGN_ANY(0), /**< custom data to be signed*/ + PL_SIGN_ETHTX(1), /**< the payload is a ethereum-tx */ + PL_SIGN_BTCTX(2), /**< the payload is a BTC-Tx-Input */ + PL_SIGN_SAFETX(3); /**< The payload is a rlp-encoded data of a Gnosys Safe Tx */ + + public final int val; + + private PayloadType(int val) { + this.val = val; + } + + private int getValue() { + return this.val; + } + + public static PayloadType getEnum(int enumVal) { + for (PayloadType v : values()) + if (v.getValue() == enumVal) return v; + return null; + } +} \ No newline at end of file diff --git a/java/src/in3/utils/Signature.java b/java/src/in3/utils/Signature.java index f62c4bbeb..b373324c3 100644 --- a/java/src/in3/utils/Signature.java +++ b/java/src/in3/utils/Signature.java @@ -21,6 +21,8 @@ private Signature(JSON data) { protected static Signature asSignature(Object o) { if (o == null) return null; + if (o instanceof Signature) + return (Signature) o; return new Signature((JSON) o); } diff --git a/java/src/in3/utils/SignatureType.java b/java/src/in3/utils/SignatureType.java index 52d330140..bf5161475 100644 --- a/java/src/in3/utils/SignatureType.java +++ b/java/src/in3/utils/SignatureType.java @@ -4,7 +4,33 @@ * Constants for the type of Signature */ public enum SignatureType { - eth_sign, - raw, - hash + eth_sign(2), + /** + * < add Ethereum Signed Message-Proefix, hash and sign the data + */ + raw(0), + /** + * < sign the data directly + */ + hash(1); + + /** + * < hash and sign the data + */ + + public final int val; + + private SignatureType(int val) { + this.val = val; + } + + private int getValue() { + return this.val; + } + + public static SignatureType getEnum(int enumVal) { + for (SignatureType v : values()) + if (v.getValue() == enumVal) return v; + return null; + } } diff --git a/java/src/in3/utils/Signer.java b/java/src/in3/utils/Signer.java index fd206cd57..a9f1f5c29 100644 --- a/java/src/in3/utils/Signer.java +++ b/java/src/in3/utils/Signer.java @@ -35,25 +35,31 @@ package in3.utils; import in3.IN3; +import in3.Loader; import in3.eth1.TransactionRequest; +import java.util.*; /** * a Interface responsible for signing data or transactions. */ -public interface Signer { - /** - * optiional method which allows to change the transaction-data before sending - * it. This can be used for redirecting it through a multisig. - */ - TransactionRequest prepareTransaction(IN3 in3, TransactionRequest tx); +public abstract class Signer { + static { + Loader.loadLibrary(); + } /** - * returns true if the account is supported (or unlocked) + * returns the accounts supported by the wallet */ - boolean canSign(String address); + public abstract String[] getAccounts(); /** * signing of the raw data. */ - String sign(String data, String address); + public abstract byte[] sign(String data, String address, SignatureType signtype, PayloadType payloadType, JSON meta) throws Exception; + + public static native String getAddressFromKey(String key); + + public static native byte[] signData(String key, String data, SignatureType signatureType); + + public static native String decodeKeystore(String keystore, String passwd); } diff --git a/java/src/in3_jni.c b/java/src/in3_jni.c index 87a0d9ea0..2b7a8221a 100644 --- a/java/src/in3_jni.c +++ b/java/src/in3_jni.c @@ -38,8 +38,10 @@ #include "../../c/src/core/client/client.h" #include "../../c/src/core/client/keys.h" #include "../../c/src/core/client/plugin.h" +#include "../../c/src/core/client/request_internal.h" #include "../../c/src/core/client/version.h" #include "../../c/src/core/util/bitset.h" +#include "../../c/src/core/util/bytes.h" #include "../../c/src/core/util/log.h" #include "../../c/src/core/util/mem.h" #include "../../c/src/init/in3_init.h" @@ -491,11 +493,11 @@ JNIEXPORT jobject JNICALL Java_in3_eth1_TransactionRequest_abiDecode(JNIEnv* env } /* - * Class: in3_eth1_SimpleWallet + * Class: in3_utils_Signer * Method: getAddressFromKey * Signature: (Ljava/lang/String;)Ljava/lang/String; */ -JNIEXPORT jstring JNICALL Java_in3_eth1_SimpleWallet_getAddressFromKey(JNIEnv* env, jclass clz, jstring jkey) { +JNIEXPORT jstring JNICALL Java_in3_utils_Signer_getAddressFromKey(JNIEnv* env, jclass clz, jstring jkey) { UNUSED_VAR(clz); const char* key = (*env)->GetStringUTFChars(env, jkey, 0); @@ -513,35 +515,47 @@ JNIEXPORT jstring JNICALL Java_in3_eth1_SimpleWallet_getAddressFromKey(JNIEnv* e } /* - * Class: in3_eth1_SimpleWallet + * Class: in3_utils_Signer * Method: signData * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; */ -JNIEXPORT jstring JNICALL Java_in3_eth1_SimpleWallet_signData(JNIEnv* env, jclass clz, jstring jkey, jstring jdata) { +JNIEXPORT jbyteArray JNICALL Java_in3_utils_Signer_signData(JNIEnv* env, jclass clz, jstring jkey, jstring jdata, jobject signatureTypeObj) { + jbyteArray res = (*env)->NewByteArray(env, 65); + UNUSED_VAR(clz); - const char* key = (*env)->GetStringUTFChars(env, jkey, 0); - const char* data = (*env)->GetStringUTFChars(env, jdata, 0); - jstring res = NULL; + const char* key = (*env)->GetStringUTFChars(env, jkey, 0); + const char* data = (*env)->GetStringUTFChars(env, jdata, 0); + int data_l = strlen(data) / 2 - 1; - char* tmp = eth_wallet_sign(key, data); + jmethodID sisgnatureTypeGetValueMethod = (*env)->GetMethodID(env, (*env)->FindClass(env, "in3/utils/SignatureType"), "getValue", "()I"); + jint jSignType = (*env)->CallIntMethod(env, signatureTypeObj, sisgnatureTypeGetValueMethod); - if (tmp != NULL) { - res = (*env)->NewStringUTF(env, tmp); + uint8_t key_bytes[32], *data_bytes = alloca(data_l + 1); + if (data[0] == '0' && data[1] == 'x') { + data_l = hex_to_bytes((char*) data + 2, -1, data_bytes, data_l + 1); } + else { + data_l = hex_to_bytes((char*) data, -1, data_bytes, data_l + 1); + } + hex_to_bytes((char*) key, -1, key_bytes, 32); - _free(tmp); + bytes_t signature = sign_with_pk(key_bytes, bytes(data_bytes, data_l), jSignType); + if (signature.len == 65) + (*env)->SetByteArrayRegion(env, res, 0, signature.len, (jbyte*) signature.data); + if (signature.data) _free(signature.data); (*env)->ReleaseStringUTFChars(env, jkey, key); (*env)->ReleaseStringUTFChars(env, jdata, data); + return res; } /* - * Class: in3_eth1_SimpleWallet + * Class: in3_utils_Signer * Method: decodeKeystore * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; */ -JNIEXPORT jstring JNICALL Java_in3_eth1_SimpleWallet_decodeKeystore(JNIEnv* env, jclass clz, jstring json, jstring passphrase) { +JNIEXPORT jstring JNICALL Java_in3_utils_Signer_decodeKeystore(JNIEnv* env, jclass clz, jstring json, jstring passphrase) { UNUSED_VAR(clz); UNUSED_VAR(env); UNUSED_VAR(json); @@ -549,18 +563,28 @@ JNIEXPORT jstring JNICALL Java_in3_eth1_SimpleWallet_decodeKeystore(JNIEnv* env, return NULL; } +jobject get_signer(in3_req_t* ctx) { + void* jp = get_java_obj_ptr(ctx->client); + if (jp == NULL) return NULL; + jclass cls = (*jni)->GetObjectClass(jni, jp); + jmethodID mid = (*jni)->GetMethodID(jni, cls, "getSigner", "()Lin3/utils/Signer;"); + return (*jni)->CallObjectMethod(jni, jp, mid); +} + +// This assumes a getEnum method which is not natural to every Enum, this will only work with custom ones. +jobject get_enum(const char* qualified_class_name, const char* getter_name, int value) { + jclass cls = (*jni)->FindClass(jni, qualified_class_name); + jmethodID mid = (*jni)->GetStaticMethodID(jni, cls, "getEnum", getter_name); + return (jobject) (*jni)->CallStaticObjectMethod(jni, cls, mid, value); +} + // in3_ret_t jsign(void* pk, d_signature_type_t type, bytes_t message, bytes_t account, uint8_t* dst) { in3_ret_t jsign(in3_sign_ctx_t* sc) { in3_req_t* ctx = (in3_req_t*) sc->req; if (ctx == NULL) return IN3_EIGNORE; - void* jp = get_java_obj_ptr(ctx->client); - in3_log_debug(":: jsign for %p === %p\n", ctx->client, jp); - if (jp == NULL) return IN3_EIGNORE; - jclass cls = (*jni)->GetObjectClass(jni, jp); - jmethodID mid = (*jni)->GetMethodID(jni, cls, "getSigner", "()Lin3/utils/Signer;"); - jobject signer = (*jni)->CallObjectMethod(jni, jp, mid); + jobject signer = get_signer(ctx); - if (!signer) return IN3_EIGNORE; + if (!signer || !sc->account.data) return IN3_EIGNORE; char *data = alloca(sc->message.len * 2 + 3), address[43]; data[0] = address[0] = '0'; @@ -568,19 +592,63 @@ in3_ret_t jsign(in3_sign_ctx_t* sc) { bytes_to_hex(sc->message.data, sc->message.len, data + 2); bytes_to_hex(sc->account.data, sc->account.len, address + 2); - jstring jdata = (*jni)->NewStringUTF(jni, data); - jstring jaddress = (*jni)->NewStringUTF(jni, address); - cls = (*jni)->GetObjectClass(jni, signer); - mid = (*jni)->GetMethodID(jni, cls, "sign", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"); - jstring jsignature = (*jni)->CallObjectMethod(jni, signer, mid, jdata, jaddress); + jobject jSignatureType = get_enum("in3/utils/SignatureType", "(I)Lin3/utils/SignatureType;", sc->type); + jobject jPayloadType = get_enum("in3/utils/PayloadType", "(I)Lin3/utils/PayloadType;", sc->payload_type); + jstring jdata = (*jni)->NewStringUTF(jni, data); + jstring jaddress = (*jni)->NewStringUTF(jni, address); + jclass cls = (*jni)->GetObjectClass(jni, signer); + + jmethodID mid = (*jni)->GetMethodID(jni, cls, "sign", "(Ljava/lang/String;Ljava/lang/String;Lin3/utils/SignatureType;Lin3/utils/PayloadType;Lin3/utils/JSON;)[B"); + + (*jni)->ExceptionClear(jni); + jbyteArray jsignature = (*jni)->CallObjectMethod(jni, signer, mid, jdata, jaddress, jSignatureType, jPayloadType, toObject(jni, sc->meta)); + jthrowable signing_exception = (*jni)->ExceptionOccurred(jni); + + if (signing_exception) { + jclass cls = (*jni)->GetObjectClass(jni, signing_exception); + mid = (*jni)->GetMethodID(jni, cls, "getMessage", "()Ljava/lang/String;"); + jstring jmsg = (*jni)->CallObjectMethod(jni, signing_exception, mid); + char* msg = (char*) (*jni)->GetStringUTFChars(jni, jmsg, 0); + + (*jni)->ExceptionClear(jni); + return req_set_error(sc->req, msg, IN3_ERPC); + } if (!jsignature) return IN3_EIGNORE; - const char* signature = (*jni)->GetStringUTFChars(jni, jsignature, 0); - int l = (strlen(signature) + 1) / 2; - if (l && signature[0] == '0' && signature[1] == 'x') l--; + + int l = (*jni)->GetArrayLength(jni, jsignature); sc->signature = bytes(_malloc(l), l); - hex_to_bytes((char*) signature, -1, sc->signature.data, l); - (*jni)->ReleaseStringUTFChars(jni, jsignature, signature); + (*jni)->GetByteArrayRegion(jni, jsignature, 0, l, (jbyte*) sc->signature.data); + + return IN3_OK; +} + +// in3_ret_t jsign(void* pk, d_signature_type_t type, bytes_t message, bytes_t account, uint8_t* dst) { +in3_ret_t jsign_accounts(in3_sign_account_ctx_t* sc) { + in3_req_t* ctx = (in3_req_t*) sc->req; + if (ctx == NULL) return IN3_EIGNORE; + + jobject signer = get_signer(ctx); + if (signer == NULL) return IN3_EIGNORE; + + jclass cls = (*jni)->GetObjectClass(jni, signer); + jmethodID mid = (*jni)->GetMethodID(jni, cls, "getAccounts", "()[Ljava/lang/String;"); + jobjectArray jaccounts = (*jni)->CallObjectMethod(jni, signer, mid); + int accounts_total = (*jni)->GetArrayLength(jni, jaccounts); + + if (!jaccounts || accounts_total == 0) return IN3_EIGNORE; + + // This assumption is incorrect as anyone could just implement the signer. + sc->accounts_len = accounts_total * 20; + sc->accounts = _malloc(accounts_total * 20); + + for (int i = 0; i < accounts_total; ++i) { + jstring jaccount = (*jni)->GetObjectArrayElement(jni, jaccounts, i); + char* account = (char*) (*jni)->GetStringUTFChars(jni, jaccount, 0); + hex_to_bytes(account, -1, sc->accounts + i * 20, 20); + (*jni)->ReleaseStringUTFChars(jni, jaccount, account); + } + return IN3_OK; } @@ -632,8 +700,11 @@ JNIEXPORT jstring JNICALL Java_in3_ipfs_API_base64Encode(JNIEnv* env, jobject ob static in3_ret_t jsign_fn(void* data, in3_plugin_act_t action, void* ctx) { UNUSED_VAR(data); - UNUSED_VAR(action); - return jsign(ctx); + switch (action) { + case PLGN_ACT_SIGN: return jsign(ctx); + case PLGN_ACT_SIGN_ACCOUNT: return jsign_accounts(ctx); + default: return IN3_ENOTSUP; + } } /* @@ -645,12 +716,12 @@ JNIEXPORT jlong JNICALL Java_in3_IN3_init(JNIEnv* env, jobject ob, jlong jchain) in3_init(); in3_t* in3 = in3_for_chain(jchain); void* p = (*env)->NewGlobalRef(env, ob); - // in3_log_set_level(LOG_TRACE); - // in3_log_set_quiet(false); + // in3_log_set_level(LOG_TRACE); + // in3_log_set_quiet(false); in3_log_debug("New Global ref for %p === %p\n", ob, p); in3_set_storage_handler(in3, storage_get_item, storage_set_item, storage_clear, p); in3_plugin_register(in3, PLGN_ACT_TRANSPORT, Java_in3_IN3_transport, NULL, true); - in3_plugin_register(in3, PLGN_ACT_SIGN, jsign_fn, p, false); + in3_plugin_register(in3, PLGN_ACT_SIGN | PLGN_ACT_SIGN_ACCOUNT, jsign_fn, p, false); jni = env; // turn to debug diff --git a/java/src/in3_jni.h b/java/src/in3_jni.h index b01695ef5..4f00014cb 100644 --- a/java/src/in3_jni.h +++ b/java/src/in3_jni.h @@ -179,25 +179,25 @@ JNIEXPORT jobject JNICALL Java_in3_eth1_TransactionRequest_abiDecode(JNIEnv*, jc JNIEXPORT jobject JNICALL Java_in3_utils_JSON_parse(JNIEnv*, jclass, jstring); /* - * Class: in3_eth1_SimpleWallet + * Class: in3_utils_Signer * Method: getAddressFromKey * Signature: (Ljava/lang/String;)Ljava/lang/String; */ -JNIEXPORT jstring JNICALL Java_in3_eth1_SimpleWallet_getAddressFromKey(JNIEnv*, jclass, jstring); +JNIEXPORT jstring JNICALL Java_in3_utils_Signer_getAddressFromKey(JNIEnv*, jclass, jstring); /* - * Class: in3_eth1_SimpleWallet + * Class: in3_utils_Signer * Method: signData * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; */ -JNIEXPORT jstring JNICALL Java_in3_eth1_SimpleWallet_signData(JNIEnv*, jclass, jstring, jstring); +JNIEXPORT jstring JNICALL Java_in3_utils_Signer_signData(JNIEnv* env, jclass clz, jstring jkey, jstring jdata, jobject signatureTypeObj); /* - * Class: in3_eth1_SimpleWallet + * Class: in3_utils_Signer * Method: decodeKeystore * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; */ -JNIEXPORT jstring JNICALL Java_in3_eth1_SimpleWallet_decodeKeystore(JNIEnv*, jclass, jstring, jstring); +JNIEXPORT jstring JNICALL Java_in3_utils_Signer_decodeKeystore(JNIEnv*, jclass, jstring, jstring); /* * Class: in3_Loader diff --git a/java/test/in3/eth1/SimpleWalletTest.java b/java/test/in3/eth1/SimpleWalletTest.java index 94f6f98c0..594fa170a 100644 --- a/java/test/in3/eth1/SimpleWalletTest.java +++ b/java/test/in3/eth1/SimpleWalletTest.java @@ -1,6 +1,8 @@ package in3.eth1; import in3.eth1.SimpleWallet; +import in3.utils.PayloadType; +import in3.utils.SignatureType; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -15,23 +17,13 @@ public void setupSigner() { @Test public void sign() { - String pk = "0x889dbed9450f7a4b68e0732ccb7cd016dab158e6946d16158f2736fda1143ca6"; - String address = wallet.addRawKey(pk); + String pk = "0x889dbed9450f7a4b68e0732ccb7cd016dab158e6946d16158f2736fda1143ca6"; + String address = wallet.addRawKey(pk); + byte[] expectedSignature = new byte[] {96, 52, 115, 0, -46, -117, 73, 50, 56, 46, -98, -81, 100, 55, 71, -85, -118, 54, 62, 94, 82, -1, 110, 30, 0, 104, -84, 67, -90, -55, -108, -21, 61, -77, -48, 62, 34, 107, -10, -38, 64, -119, -79, -63, 26, -14, 110, -16, -57, -40, -68, -97, -83, 89, -81, -112, 33, 31, -34, -8, -107, 42, -84, 108, 0}; Assertions.assertEquals(address, "0x082977959d0C5A1bA627720ac753Ec2ADB5Bd7d0".toLowerCase()); - Assertions.assertEquals( - wallet.sign("1e194c68360307cfb715bf17878791ad1ced8da7d2e5f42b691074c577f41eac", address), - "0xf16dcaa830a3f710e28444df7df85fa927d8a66f789196fc2a3b934c829dbcaa5329be0711daba3b0c85ab23f1adb32c4e88fd8cb42b951d3be40af1bbd92e7400"); - } - - @Test - public void canSign() { - String pk = "0x889dbed9450f7a4b68e0732ccb7cd016dab158e6946d16158f2736fda1143ca6"; - String address = wallet.addRawKey(pk); - - String anotherAddress = "0x06012c8cf97BEaD5deAe237070F9587f8E7A266d"; - - Assertions.assertTrue(wallet.canSign(address)); - Assertions.assertFalse(wallet.canSign(anotherAddress)); + Assertions.assertArrayEquals(wallet.sign("1e194c68360307cfb715bf17878791ad1ced8da7d2e5f42b691074c577f41eac", + address, SignatureType.eth_sign, PayloadType.PL_SIGN_ETHTX, null), + expectedSignature); } } From c1d15bb8dae14c3911b080baafe1694d95f60253 Mon Sep 17 00:00:00 2001 From: Leonardo Souza Date: Fri, 29 Oct 2021 10:27:10 +0200 Subject: [PATCH 084/101] WIP --- c/src/verifier/btc/btc.c | 84 ++++++++++++++++++++++++++++++ c/src/verifier/btc/btc_serialize.c | 2 +- c/src/verifier/btc/btc_sign.c | 6 +-- c/src/verifier/btc/btc_types.c | 30 +++++++++++ c/src/verifier/btc/btc_types.h | 4 ++ 5 files changed, 122 insertions(+), 4 deletions(-) diff --git a/c/src/verifier/btc/btc.c b/c/src/verifier/btc/btc.c index b7a240383..0d68f6e00 100644 --- a/c/src/verifier/btc/btc.c +++ b/c/src/verifier/btc/btc.c @@ -491,6 +491,90 @@ static in3_ret_t in3_verify_btc(btc_target_conf_t* conf, in3_vctx_t* vc) { return btc_verify_tx(conf, vc, tx_hash_bytes, json, block_hash ? hash : NULL); } #endif + + // #if !defined(RPC_ONLY) || defined(RPC_GETUTXOS) + + // // fetch whole list of utxos + // if (VERIFY_RPC("getutxos")) { + // REQUIRE_EXPERIMENTAL(vc->req, "btc") + // // Get raw unsigned transaction + // // As we will have custody of the user priv keys, this should be obtained from our server somehow + // // sign transaction + // // return raw signed transaction + // } + // #endif + + // #if !defined(RPC_ONLY) || defined(RPC_SELECTUTXOS) + + // // TODO: Define if it is really necessary to have an RPC for this or if we should + // // only do this in the background when sending a transaction. + // if (VERIFY_RPC("selectutxos")) { + // REQUIRE_EXPERIMENTAL(vc->req, "btc") + // // Get list of outputs we want to send in out transaction + // // Get list of unspended transaction outputs (utxos) + // // Select "best" group of utxos to meet the requirements of our + // // return a list with the selected utxos + // } + // #endif + +#if !defined(RPC_ONLY) || defined(RPC_SENDTRANSACTION) + + // SERVER: sendtransaction(raw_signed_tx) + if (VERIFY_RPC("sendtransaction")) { + REQUIRE_EXPERIMENTAL(vc->req, "btc") + // This is the RPC that abstracts most of what is done in the background before sending a transaction: + // Get outputs we want to send + d_token_t* outputs = d_get_at(params, 0); + d_token_t* utxo_list = d_get_at(params, 1); + // select "best" set of UTXOs + // btc_utxo_t* utxo_list = NULL; + uint32_t miner_fee = 0, outputs_total = 0, utxo_total = 0; + // ---- select utxos here + // create output for receiving the transaction "change", discounting miner fee + btc_tx_out_t tx_out_change; + init_tx_out(&tx_out_change); + tx_out_change.value = utxo_total - miner_fee - outputs_total; + // create raw unsigned transaction using selected set of utxos (inputs) and outputs (both received in Command Line and created "change") + // Obtain private key + // Sign previously obtained unsigned transaction using private key + // Send transaction to in3 server + // return succes (transaction hash, so the user can look for it online) or error code + } +#endif + +#if !defined(RPC_ONLY) || defined(RPC_BUILDUNSIGNEDTRANSACTION) + + if (VERIFY_RPC("buildunsignedtransaction")) { + REQUIRE_EXPERIMENTAL(vc->req, "btc") + // Get inputs list + // Get outputs list + // Get other important parameters (witnesses, tx_type (ex: p2pk), fees, sighash_type, etc.) + // Build the unsigned transaction + // return raw unsigned transaction + } +#endif + +#if !defined(RPC_ONLY) || defined(RPC_SIGNTRANSACTION) + + if (VERIFY_RPC("signtransaction")) { + REQUIRE_EXPERIMENTAL(vc->req, "btc") + // Get raw unsigned transaction + // As we will have custody of the user priv keys, this should be obtained from our server somehow + // sign transaction + // return raw signed transaction + } +#endif + +#if !defined(RPC_ONLY) || defined(RPC_SENDRAWTRANSACTION) + + if (VERIFY_RPC("sendrawtransaction")) { + REQUIRE_EXPERIMENTAL(vc->req, "btc") + // Get raw signed transaction + // verify if transaction is well-formed and signed before sending + // send transaction to in3 server + // return success or error code + } +#endif return IN3_EIGNORE; } diff --git a/c/src/verifier/btc/btc_serialize.c b/c/src/verifier/btc/btc_serialize.c index 0f59d1867..cc8b4257f 100644 --- a/c/src/verifier/btc/btc_serialize.c +++ b/c/src/verifier/btc/btc_serialize.c @@ -126,7 +126,7 @@ void long_to_compact_uint(bytes_t* buf, uint32_t index, uint64_t value) { // fill buffer with value if (len > 1) { for (int i = 0; i < (len - 1); i++) { - buf->data[i + index] = (uint8_t) ((value >> (i << 1)) && 0xff); + buf->data[i + index] = (uint8_t) ((value >> (i << 1)) & 0xff); } } } diff --git a/c/src/verifier/btc/btc_sign.c b/c/src/verifier/btc/btc_sign.c index 03efa229e..327ff4cfd 100644 --- a/c/src/verifier/btc/btc_sign.c +++ b/c/src/verifier/btc/btc_sign.c @@ -5,10 +5,10 @@ // Fill tx_in fields, preparing the input for signing // WARNING: You need to free tx_in->prev_tx_hash after calling this function -static void init_tx_in(const btc_utxo_t* utxo, btc_tx_in_t* tx_in) { +static void prepare_tx_in(const btc_utxo_t* utxo, btc_tx_in_t* tx_in) { if (!utxo || !tx_in) { // TODO: Implement better error treatment - printf("ERROR: in init_tx_in: function arguments can not be null!\n"); + printf("ERROR: in prepare_tx_in: function arguments can not be null!\n"); return; } tx_in->prev_tx_index = utxo->tx_index; @@ -111,7 +111,7 @@ void btc_sign_tx(btc_tx_t* tx, const btc_utxo_t* selected_utxo_list, uint32_t ut // -- for each pub_key (assume we only have one pub key for now): // TODO: Allow setting a specific pub_key for each input btc_tx_in_t tx_in; - init_tx_in(&selected_utxo_list[i], &tx_in); + prepare_tx_in(&selected_utxo_list[i], &tx_in); btc_sign_tx_in(tx, &selected_utxo_list[i].tx_out, priv_key, &tx_in, BTC_SIGHASH_ALL); add_input_to_tx(tx, &tx_in); _free(tx_in.script.data); diff --git a/c/src/verifier/btc/btc_types.c b/c/src/verifier/btc/btc_types.c index 41da29f6e..a399547bb 100644 --- a/c/src/verifier/btc/btc_types.c +++ b/c/src/verifier/btc/btc_types.c @@ -18,6 +18,36 @@ typedef enum btc_tx_field { OUTPUT } btc_tx_field_t; +void btc_init_tx(btc_tx_t* tx) { + tx->all.len = 0; + tx->all.data = NULL; + tx->version = 1; + tx->flag = 0; + tx->input_count = 0; + tx->output_count = 0; + tx->input.len = 0; + tx->input.data = NULL; + tx->output.len = 0; + tx->output.data = NULL; + tx->witnesses.len = 0; + tx->witnesses.data = NULL; + tx->lock_time = 0; +} + +void btc_init_tx_in(btc_tx_in_t* tx_in) { + tx_in->prev_tx_hash = NULL; + tx_in->prev_tx_index = 0; + tx_in->script.len = 0; + tx_in->script.data = NULL; + tx_in->sequence = 0xffffffff; +} + +void btc_init_tx_out(btc_tx_out_t* tx_out) { + tx_out->script.len = 0; + tx_out->script.data = NULL; + tx_out->value = 0; +} + uint8_t* btc_parse_tx_in(uint8_t* data, btc_tx_in_t* dst, uint8_t* limit) { uint64_t len; dst->prev_tx_hash = data; diff --git a/c/src/verifier/btc/btc_types.h b/c/src/verifier/btc/btc_types.h index 06c022778..423f7cadc 100644 --- a/c/src/verifier/btc/btc_types.h +++ b/c/src/verifier/btc/btc_types.h @@ -36,6 +36,10 @@ typedef struct btc_utxo { btc_tx_out_t tx_out; } btc_utxo_t; +void btc_init_tx(btc_tx_t* tx); +void btc_init_tx_in(btc_tx_in_t* tx_in); +void btc_init_tx_out(btc_tx_out_t* tx_out); + in3_ret_t btc_parse_tx(bytes_t tx, btc_tx_t* dst); in3_ret_t btc_serialize_tx(btc_tx_t* tx, bytes_t* dst); in3_ret_t btc_tx_id(btc_tx_t* tx, bytes32_t dst); From a36498b30828da37c5de9ba983ab77642c55ccb0 Mon Sep 17 00:00:00 2001 From: Leonardo Souza Date: Fri, 29 Oct 2021 12:21:34 +0200 Subject: [PATCH 085/101] Implement support for signing transaction with multiple inputs --- c/src/verifier/btc/btc.c | 2 +- c/src/verifier/btc/btc_sign.c | 32 +++++++++++++++++++++++++++----- c/src/verifier/btc/btc_sign.h | 2 +- 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/c/src/verifier/btc/btc.c b/c/src/verifier/btc/btc.c index 0d68f6e00..bdf92d0d4 100644 --- a/c/src/verifier/btc/btc.c +++ b/c/src/verifier/btc/btc.c @@ -532,7 +532,7 @@ static in3_ret_t in3_verify_btc(btc_target_conf_t* conf, in3_vctx_t* vc) { // ---- select utxos here // create output for receiving the transaction "change", discounting miner fee btc_tx_out_t tx_out_change; - init_tx_out(&tx_out_change); + btc_init_tx_out(&tx_out_change); tx_out_change.value = utxo_total - miner_fee - outputs_total; // create raw unsigned transaction using selected set of utxos (inputs) and outputs (both received in Command Line and created "change") // Obtain private key diff --git a/c/src/verifier/btc/btc_sign.c b/c/src/verifier/btc/btc_sign.c index 327ff4cfd..ceb0648ca 100644 --- a/c/src/verifier/btc/btc_sign.c +++ b/c/src/verifier/btc/btc_sign.c @@ -20,7 +20,7 @@ static void prepare_tx_in(const btc_utxo_t* utxo, btc_tx_in_t* tx_in) { } // WARNING: You need to free tx_in->script.data after calling this function! -void btc_sign_tx_in(const btc_tx_t* tx, const btc_tx_out_t* utxo, const bytes_t* priv_key, btc_tx_in_t* tx_in, uint8_t sighash) { +void btc_sign_tx_in(const btc_tx_t* tx, const btc_utxo_t* utxo_list, const uint32_t utxo_index, const bytes_t* priv_key, btc_tx_in_t* tx_in, uint8_t sighash) { if (!tx_in || !priv_key) { // TODO: Implement better error handling printf("ERROR: in btc_sign_tx_in: function arguments cannot be NULL."); @@ -32,10 +32,12 @@ void btc_sign_tx_in(const btc_tx_t* tx, const btc_tx_out_t* utxo, const bytes_t* return; } + // Generate an unsigned transaction. This will be used to henerate the hash provided to + // the ecdsa signing algorithm btc_tx_t tmp_tx; tmp_tx.version = tx->version; tmp_tx.flag = 0; // TODO: Implement segwit support - tmp_tx.input_count = 1; // TODO: support more than one input + tmp_tx.input_count = 0; tmp_tx.output_count = tx->output_count; tmp_tx.output.len = tx->output.len; tmp_tx.output.data = alloca(sizeof(uint8_t) * tmp_tx.output.len); @@ -44,8 +46,28 @@ void btc_sign_tx_in(const btc_tx_t* tx, const btc_tx_out_t* utxo, const bytes_t* tmp_tx.lock_time = tx->lock_time; // TODO: This should probably be set before calling the signer function. If this is done outside this function, then the utxo is probably not needed. - tx_in->script = utxo->script; // This should temporarily be the scriptPubKey of the output we want to redeem - btc_serialize_tx_in(tx_in, &tmp_tx.input); + // Include inputs into unsigned tx + btc_tx_in_t tmp_tx_in; + for (uint32_t i = 0; i < tx->input_count; i++) { + tmp_tx_in.prev_tx_hash = utxo_list[i].tx_hash; + tmp_tx_in.prev_tx_index = utxo_list[i].tx_index; + tmp_tx_in.sequence = 0xffffffff; // Until BIP 125 sequence fields were unused. TODO: Implement support for BIP 125 + if (i == utxo_index) { + // We found our target input for signing. Write data to the "permanent" tx_in structure + tx_in->prev_tx_hash = utxo_list[i].tx_hash; + tx_in->prev_tx_index = utxo_list[i].tx_index; + tx_in->sequence = 0xffffffff; // Until BIP 125 sequence fields were unused. TODO: Implement support for BIP 125 + tx_in->script = utxo_list[utxo_index].tx_out.script; // This should temporarily be the scriptPubKey of the output we want to redeem. + tmp_tx_in.script = utxo_list[utxo_index].tx_out.script; // We also need to include the "unsigned" script in our transaction + } + else { + tmp_tx_in.script.data = NULL; + tmp_tx_in.script.len = 0; + } + add_input_to_tx(&tmp_tx, &tmp_tx_in); + } + // tx_in->script = utxo_list[utxo_index]->script; // This should temporarily be the scriptPubKey of the output we want to redeem + // btc_serialize_tx_in(tx_in, &tmp_tx.input); // prepare array for hashing btc_serialize_tx(&tmp_tx, &(tmp_tx.all)); @@ -112,7 +134,7 @@ void btc_sign_tx(btc_tx_t* tx, const btc_utxo_t* selected_utxo_list, uint32_t ut // TODO: Allow setting a specific pub_key for each input btc_tx_in_t tx_in; prepare_tx_in(&selected_utxo_list[i], &tx_in); - btc_sign_tx_in(tx, &selected_utxo_list[i].tx_out, priv_key, &tx_in, BTC_SIGHASH_ALL); + btc_sign_tx_in(tx, selected_utxo_list, i, priv_key, &tx_in, BTC_SIGHASH_ALL); add_input_to_tx(tx, &tx_in); _free(tx_in.script.data); _free(tx_in.prev_tx_hash); diff --git a/c/src/verifier/btc/btc_sign.h b/c/src/verifier/btc/btc_sign.h index 9ac2c8d81..e819441c5 100644 --- a/c/src/verifier/btc/btc_sign.h +++ b/c/src/verifier/btc/btc_sign.h @@ -9,7 +9,7 @@ #define BTC_SIGHASH_ANYONECANPAY 0x80 void create_raw_tx(btc_tx_in_t* tx_in, uint32_t tx_in_len, btc_tx_out_t* tx_out, uint32_t tx_out_len, uint32_t lock_time, bytes_t* dst_raw_tx); -void btc_sign_tx_in(const btc_tx_t* tx, const btc_tx_out_t* utxo, const bytes_t* priv_key, btc_tx_in_t* tx_in, uint8_t sighash); +void btc_sign_tx_in(const btc_tx_t* tx, const btc_utxo_t* utxo_list, const uint32_t utxo_index, const bytes_t* priv_key, btc_tx_in_t* tx_in, uint8_t sighash); void btc_sign_tx(btc_tx_t* tx, const btc_utxo_t* selected_utxo_list, uint32_t utxo_list_len, bytes_t* priv_key); #endif \ No newline at end of file From ba38467a8f3bfbe0376299e6a179b12d5e201fea Mon Sep 17 00:00:00 2001 From: Leonardo Souza Date: Fri, 29 Oct 2021 19:07:55 +0200 Subject: [PATCH 086/101] Fix btc transaction signature failing for multiple inputs --- c/src/verifier/btc/btc_sign.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/c/src/verifier/btc/btc_sign.c b/c/src/verifier/btc/btc_sign.c index ceb0648ca..88172efe9 100644 --- a/c/src/verifier/btc/btc_sign.c +++ b/c/src/verifier/btc/btc_sign.c @@ -11,12 +11,17 @@ static void prepare_tx_in(const btc_utxo_t* utxo, btc_tx_in_t* tx_in) { printf("ERROR: in prepare_tx_in: function arguments can not be null!\n"); return; } + tx_in->prev_tx_index = utxo->tx_index; tx_in->prev_tx_hash = malloc(32 * sizeof(uint8_t)); memcpy(tx_in->prev_tx_hash, utxo->tx_hash, 32); - tx_in->script.len = 0; - tx_in->script.data = NULL; - tx_in->sequence = 0xffffffff; + + // Before signing, input script field should temporarilly be equal to the utxo we want to redeem + tx_in->script.len = utxo->tx_out.script.len; + tx_in->script.data = malloc(tx_in->script.len * sizeof(uint8_t)); + memcpy(tx_in->script.data, utxo->tx_out.script.data, tx_in->script.len); + + tx_in->sequence = 0xffffffff; // Until BIP 125 sequence fields were unused. TODO: Implement support for BIP 125 } // WARNING: You need to free tx_in->script.data after calling this function! @@ -49,25 +54,18 @@ void btc_sign_tx_in(const btc_tx_t* tx, const btc_utxo_t* utxo_list, const uint3 // Include inputs into unsigned tx btc_tx_in_t tmp_tx_in; for (uint32_t i = 0; i < tx->input_count; i++) { - tmp_tx_in.prev_tx_hash = utxo_list[i].tx_hash; - tmp_tx_in.prev_tx_index = utxo_list[i].tx_index; - tmp_tx_in.sequence = 0xffffffff; // Until BIP 125 sequence fields were unused. TODO: Implement support for BIP 125 if (i == utxo_index) { - // We found our target input for signing. Write data to the "permanent" tx_in structure - tx_in->prev_tx_hash = utxo_list[i].tx_hash; - tx_in->prev_tx_index = utxo_list[i].tx_index; - tx_in->sequence = 0xffffffff; // Until BIP 125 sequence fields were unused. TODO: Implement support for BIP 125 - tx_in->script = utxo_list[utxo_index].tx_out.script; // This should temporarily be the scriptPubKey of the output we want to redeem. - tmp_tx_in.script = utxo_list[utxo_index].tx_out.script; // We also need to include the "unsigned" script in our transaction + tmp_tx_in = *tx_in; } else { - tmp_tx_in.script.data = NULL; - tmp_tx_in.script.len = 0; + tmp_tx_in.prev_tx_hash = utxo_list[i].tx_hash; + tmp_tx_in.prev_tx_index = utxo_list[i].tx_index; + tmp_tx_in.sequence = 0xffffffff; // Until BIP 125 sequence fields were unused. TODO: Implement support for BIP 125 + tmp_tx_in.script.data = NULL; + tmp_tx_in.script.len = 0; } add_input_to_tx(&tmp_tx, &tmp_tx_in); } - // tx_in->script = utxo_list[utxo_index]->script; // This should temporarily be the scriptPubKey of the output we want to redeem - // btc_serialize_tx_in(tx_in, &tmp_tx.input); // prepare array for hashing btc_serialize_tx(&tmp_tx, &(tmp_tx.all)); From 093d48f3efc90df6198c643e3f874de30425cd52 Mon Sep 17 00:00:00 2001 From: leonardotc Date: Fri, 29 Oct 2021 19:10:05 +0200 Subject: [PATCH 087/101] Add btc sendtransaction to btc rpc --- c/src/verifier/btc/btc.c | 107 +++++++++++------ c/src/verifier/btc/btc_sign.c | 57 ++++----- c/src/verifier/btc/btc_sign.h | 5 +- c/src/verifier/btc/btc_types.c | 210 ++++++++++++++++++++------------- c/src/verifier/btc/btc_types.h | 5 + c/src/verifier/btc/rpc.yml | 68 +++++++++-- 6 files changed, 293 insertions(+), 159 deletions(-) diff --git a/c/src/verifier/btc/btc.c b/c/src/verifier/btc/btc.c index bdf92d0d4..f05bb8e00 100644 --- a/c/src/verifier/btc/btc.c +++ b/c/src/verifier/btc/btc.c @@ -8,6 +8,7 @@ #include "../../verifier/eth1/nano/eth_nano.h" #include "btc_merkle.h" #include "btc_serialize.h" +#include "btc_sign.h" #include "btc_target.h" #include "btc_types.h" #include @@ -517,43 +518,6 @@ static in3_ret_t in3_verify_btc(btc_target_conf_t* conf, in3_vctx_t* vc) { // } // #endif -#if !defined(RPC_ONLY) || defined(RPC_SENDTRANSACTION) - - // SERVER: sendtransaction(raw_signed_tx) - if (VERIFY_RPC("sendtransaction")) { - REQUIRE_EXPERIMENTAL(vc->req, "btc") - // This is the RPC that abstracts most of what is done in the background before sending a transaction: - // Get outputs we want to send - d_token_t* outputs = d_get_at(params, 0); - d_token_t* utxo_list = d_get_at(params, 1); - // select "best" set of UTXOs - // btc_utxo_t* utxo_list = NULL; - uint32_t miner_fee = 0, outputs_total = 0, utxo_total = 0; - // ---- select utxos here - // create output for receiving the transaction "change", discounting miner fee - btc_tx_out_t tx_out_change; - btc_init_tx_out(&tx_out_change); - tx_out_change.value = utxo_total - miner_fee - outputs_total; - // create raw unsigned transaction using selected set of utxos (inputs) and outputs (both received in Command Line and created "change") - // Obtain private key - // Sign previously obtained unsigned transaction using private key - // Send transaction to in3 server - // return succes (transaction hash, so the user can look for it online) or error code - } -#endif - -#if !defined(RPC_ONLY) || defined(RPC_BUILDUNSIGNEDTRANSACTION) - - if (VERIFY_RPC("buildunsignedtransaction")) { - REQUIRE_EXPERIMENTAL(vc->req, "btc") - // Get inputs list - // Get outputs list - // Get other important parameters (witnesses, tx_type (ex: p2pk), fees, sighash_type, etc.) - // Build the unsigned transaction - // return raw unsigned transaction - } -#endif - #if !defined(RPC_ONLY) || defined(RPC_SIGNTRANSACTION) if (VERIFY_RPC("signtransaction")) { @@ -578,6 +542,71 @@ static in3_ret_t in3_verify_btc(btc_target_conf_t* conf, in3_vctx_t* vc) { return IN3_EIGNORE; } +in3_ret_t send_transaction(btc_target_conf_t* conf, in3_rpc_handle_ctx_t* ctx) { + UNUSED_VAR(conf); + + in3_req_t* req = ctx->req; + // This is the RPC that abstracts most of what is done in the background before sending a transaction: + // Get outputs we want to send + d_token_t* params = ctx->params; + bytes_t pub_key; + pub_key.len = 20; + TRY_PARAM_GET_REQUIRED_ADDRESS(pub_key.data, ctx, 0) + d_token_t* outputs = d_get_at(params, 1); + d_token_t* utxo_list = d_get_at(params, 2); + + // select "best" set of UTXOs + // btc_utxo_t* utxo_list = NULL; + uint32_t miner_fee = 0, outputs_total = 0, utxo_total = 0; + // ---- select utxos here + // create output for receiving the transaction "change", discounting miner fee + btc_tx_out_t tx_out_change; + btc_init_tx_out(&tx_out_change); + tx_out_change.value = utxo_total - miner_fee - outputs_total; + // create raw unsigned transaction using selected set of utxos (inputs) and outputs (both received in Command Line and created "change") + + // {"method":"sendrawtransaction", "params":["0100000001f90c6776e0aff73fdc67d57beadc283cea8c63cc7b8d48249bd79ce6a7823fc0000000008a47304402201955addf93c52fe20ce468603e97d3ea495c3072d3ebe92120ad0a200abbb51902204a9fe8e85fcee5621fc902796bbdf7ce490dc06cbfe7acb37eeb2f8c9406710e0141046d6caac248af96f6afa7f904f550253a0f3ef3f5aa2fe6838a95b216691468e2487e6222a6664e079c8edf7518defd562dbeda1e7593dfd7f0be285880a24dabffffffff01e803000000000000015100000000"]} + + bytes_t signed_tx = NULL_BYTES; + btc_tx_t tx; + btc_init_tx(&tx); + add_outputs_to_tx(outputs, &tx); + + btc_utxo_t* selected_utxo_list = NULL; + uint32_t utxo_list_len = btc_prepare_utxo(utxo_list, &selected_utxo_list); + // TODO: prepare tx + TRY(btc_sign_tx(ctx->req, &tx, selected_utxo_list, utxo_list_len, &pub_key)); + + btc_serialize_tx(&tx, &signed_tx); + sb_t sb = {0}; + sb_add_rawbytes(&sb, "\"", signed_tx, 0); + sb_add_chars(&sb, "\""); + + // now that we included the signature in the rpc-request, we can free it + the old rpc-request. + _free(signed_tx.data); + + d_token_t* result = NULL; + TRY_FINAL(req_send_sub_request(req, "sendrawtransaction", sb.data, NULL, &result, NULL), _free(sb.data)); + sb_add_json(in3_rpc_handle_start(ctx), "", result); + return in3_rpc_handle_finish(ctx); +} + +static in3_ret_t btc_handle_intern(btc_target_conf_t* conf, in3_rpc_handle_ctx_t* ctx) { + in3_req_t* req = ctx->req; + // we only handle BTC + if (req->client->chain.type != CHAIN_BTC) return IN3_EIGNORE; + + // make sure the conf is filled with data from the cache + btc_check_conf(req->client, conf); + +#if !defined(RPC_ONLY) || defined(RPC_SENDTRANSACTION) + + // SERVER: sendtransaction(raw_signed_tx) + TRY_RPC("sendtransaction", send_transaction(conf, ctx)) +#endif + return IN3_EIGNORE; +} + static in3_ret_t handle_btc(void* pdata, in3_plugin_act_t action, void* pctx) { btc_target_conf_t* conf = pdata; switch (action) { @@ -604,6 +633,8 @@ static in3_ret_t handle_btc(void* pdata, in3_plugin_act_t action, void* pctx) { return IN3_EIGNORE; return IN3_OK; } + case PLGN_ACT_RPC_HANDLE: + return btc_handle_intern(conf, pctx); case PLGN_ACT_RPC_VERIFY: return in3_verify_btc(conf, pctx); default: @@ -618,7 +649,7 @@ in3_ret_t in3_register_btc(in3_t* c) { tc->max_daps = 20; tc->max_diff = 10; tc->dap_limit = 20; - return in3_plugin_register(c, PLGN_ACT_RPC_VERIFY | PLGN_ACT_TERM | PLGN_ACT_CONFIG_GET | PLGN_ACT_CONFIG_SET, handle_btc, tc, false); + return in3_plugin_register(c, PLGN_ACT_RPC_VERIFY | PLGN_ACT_TERM | PLGN_ACT_CONFIG_GET | PLGN_ACT_CONFIG_SET | PLGN_ACT_RPC_HANDLE, handle_btc, tc, false); } /* static void print_hex(char* prefix, uint8_t* data, int len) { diff --git a/c/src/verifier/btc/btc_sign.c b/c/src/verifier/btc/btc_sign.c index 88172efe9..8f083e807 100644 --- a/c/src/verifier/btc/btc_sign.c +++ b/c/src/verifier/btc/btc_sign.c @@ -1,4 +1,7 @@ #include "btc_sign.h" +#include "../../core/client/plugin.h" +#include "../../core/client/request.h" +#include "../../core/client/request_internal.h" #include "../../third-party/crypto/secp256k1.h" #include "btc_serialize.h" #include "btc_types.h" @@ -25,28 +28,23 @@ static void prepare_tx_in(const btc_utxo_t* utxo, btc_tx_in_t* tx_in) { } // WARNING: You need to free tx_in->script.data after calling this function! -void btc_sign_tx_in(const btc_tx_t* tx, const btc_utxo_t* utxo_list, const uint32_t utxo_index, const bytes_t* priv_key, btc_tx_in_t* tx_in, uint8_t sighash) { - if (!tx_in || !priv_key) { - // TODO: Implement better error handling - printf("ERROR: in btc_sign_tx_in: function arguments cannot be NULL."); - return; +in3_ret_t btc_sign_tx_in(in3_req_t* req, const btc_tx_t* tx, const btc_utxo_t* utxo_list, const uint32_t utxo_index, const bytes_t* pub_key, btc_tx_in_t* tx_in, uint8_t sighash) { + if (!tx_in || !pub_key) { + return req_set_error(req, "ERROR: in btc_sign_tx_in: function arguments cannot be NULL.", IN3_ERPC); } // TODO: Implement support for other sighashes if (sighash != BTC_SIGHASH_ALL) { - printf("ERROR: in btc_sign_tx_in: Sighash not supported."); - return; + return req_set_error(req, "ERROR: in btc_sign_tx_in: Sighash not supported.", IN3_ERPC); } // Generate an unsigned transaction. This will be used to henerate the hash provided to // the ecdsa signing algorithm btc_tx_t tmp_tx; - tmp_tx.version = tx->version; - tmp_tx.flag = 0; // TODO: Implement segwit support - tmp_tx.input_count = 0; - tmp_tx.output_count = tx->output_count; - tmp_tx.output.len = tx->output.len; - tmp_tx.output.data = alloca(sizeof(uint8_t) * tmp_tx.output.len); - tmp_tx.witnesses.len = 0; + btc_init_tx(&tmp_tx); + tmp_tx.version = tx->version; + tmp_tx.output_count = tx->output_count; + tmp_tx.output.len = tx->output.len; + tmp_tx.output.data = alloca(sizeof(uint8_t) * tmp_tx.output.len); for (uint32_t i = 0; i < tmp_tx.output.len; i++) tmp_tx.output.data[i] = tx->output.data[i]; tmp_tx.lock_time = tx->lock_time; @@ -71,7 +69,7 @@ void btc_sign_tx_in(const btc_tx_t* tx, const btc_utxo_t* utxo_list, const uint3 btc_serialize_tx(&tmp_tx, &(tmp_tx.all)); bytes_t hash_input; hash_input.len = tmp_tx.all.len + 4; - hash_input.data = malloc(hash_input.len * sizeof(uint8_t)); + hash_input.data = alloca(hash_input.len * sizeof(uint8_t)); // TODO: Implement this in a more efficient way. Right now we copy // the whole tx just to add 4 bytes at the end of the stream @@ -85,17 +83,18 @@ void btc_sign_tx_in(const btc_tx_t* tx, const btc_utxo_t* utxo_list, const uint3 // Finally, sign transaction input // -- Obtain DER signature - uint8_t sig[65]; + bytes_t sig; + sig.data = NULL; + sig.len = 65; + bytes_t der_sig; der_sig.data = alloca(sizeof(uint8_t) * 75); - ecdsa_sign(&secp256k1, HASHER_SHA2D, priv_key->data, hash_input.data, hash_input.len, sig, sig + 64, NULL); - der_sig.len = ecdsa_sig_to_der(sig, der_sig.data); - der_sig.data[der_sig.len++] = sig[64]; // append verification byte to end of DER signature - // -- Extract public key out of the provided private key. This will be used to build the tx_in scriptSig - uint8_t pub_key[65]; - ecdsa_get_public_key65(&secp256k1, (const uint8_t*) priv_key->data, pub_key); + TRY(req_require_signature(req, SIGN_EC_BTC, PL_SIGN_BTCTX, &sig, hash_input, *pub_key, req->requests[0])) + + der_sig.len = ecdsa_sig_to_der(sig.data, der_sig.data); + der_sig.data[der_sig.len++] = sig.data[64]; // append verification byte to end of DER signature // -- build scriptSig: DER_LEN|DER_SIG|PUB_KEY_LEN|PUB_BEY uint32_t scriptsig_len = der_sig.len + 1 + 65; // DER_SIG + 1 byte PUBKEY_LEN + PUBKEY @@ -116,26 +115,30 @@ void btc_sign_tx_in(const btc_tx_t* tx, const btc_utxo_t* utxo_list, const uint3 // write pubkey i = 0; while (i < 65) { - b->data[index++] = pub_key[i++]; + b->data[index++] = pub_key->data[i++]; } // signature is complete _free(tmp_tx.all.data); _free(tmp_tx.input.data); - _free(hash_input.data); + // _free(hash_input.data); + + return IN3_OK; } -void btc_sign_tx(btc_tx_t* tx, const btc_utxo_t* selected_utxo_list, uint32_t utxo_list_len, bytes_t* priv_key) { +in3_ret_t btc_sign_tx(in3_req_t* req, btc_tx_t* tx, const btc_utxo_t* selected_utxo_list, uint32_t utxo_list_len, bytes_t* pub_key) { // for each input in a tx: for (uint32_t i = 0; i < utxo_list_len; i++) { // -- for each pub_key (assume we only have one pub key for now): // TODO: Allow setting a specific pub_key for each input btc_tx_in_t tx_in; prepare_tx_in(&selected_utxo_list[i], &tx_in); - btc_sign_tx_in(tx, selected_utxo_list, i, priv_key, &tx_in, BTC_SIGHASH_ALL); + TRY_CATCH(btc_sign_tx_in(req, tx, selected_utxo_list, i, pub_key, &tx_in, BTC_SIGHASH_ALL), + _free(tx_in.script.data); + _free(tx_in.prev_tx_hash);) add_input_to_tx(tx, &tx_in); _free(tx_in.script.data); _free(tx_in.prev_tx_hash); } - return; + return IN3_OK; } \ No newline at end of file diff --git a/c/src/verifier/btc/btc_sign.h b/c/src/verifier/btc/btc_sign.h index e819441c5..e725df6ee 100644 --- a/c/src/verifier/btc/btc_sign.h +++ b/c/src/verifier/btc/btc_sign.h @@ -8,8 +8,7 @@ #define BTC_SIGHASH_SINGLE 0x3 #define BTC_SIGHASH_ANYONECANPAY 0x80 -void create_raw_tx(btc_tx_in_t* tx_in, uint32_t tx_in_len, btc_tx_out_t* tx_out, uint32_t tx_out_len, uint32_t lock_time, bytes_t* dst_raw_tx); -void btc_sign_tx_in(const btc_tx_t* tx, const btc_utxo_t* utxo_list, const uint32_t utxo_index, const bytes_t* priv_key, btc_tx_in_t* tx_in, uint8_t sighash); -void btc_sign_tx(btc_tx_t* tx, const btc_utxo_t* selected_utxo_list, uint32_t utxo_list_len, bytes_t* priv_key); +in3_ret_t btc_sign_tx_in(in3_req_t* ctx, const btc_tx_t* tx, const btc_utxo_t* utxo_list, const uint32_t utxo_index, const bytes_t* pub_key, btc_tx_in_t* tx_in, uint8_t sighash); +in3_ret_t btc_sign_tx(in3_req_t* ctx, btc_tx_t* tx, const btc_utxo_t* selected_utxo_list, uint32_t utxo_list_len, bytes_t* pub_key); #endif \ No newline at end of file diff --git a/c/src/verifier/btc/btc_types.c b/c/src/verifier/btc/btc_types.c index a399547bb..e0001946b 100644 --- a/c/src/verifier/btc/btc_types.c +++ b/c/src/verifier/btc/btc_types.c @@ -1,5 +1,6 @@ #include "btc_types.h" #include "../../core/util/mem.h" +#include "../../core/util/utils.h" #include "btc_serialize.h" // Transaction fixed size values @@ -14,24 +15,13 @@ #define BTC_TX_OUT_VALUE_SIZE_BYTES 8 typedef enum btc_tx_field { - INPUT, - OUTPUT + BTC_INPUT, + BTC_OUTPUT } btc_tx_field_t; void btc_init_tx(btc_tx_t* tx) { - tx->all.len = 0; - tx->all.data = NULL; - tx->version = 1; - tx->flag = 0; - tx->input_count = 0; - tx->output_count = 0; - tx->input.len = 0; - tx->input.data = NULL; - tx->output.len = 0; - tx->output.data = NULL; - tx->witnesses.len = 0; - tx->witnesses.data = NULL; - tx->lock_time = 0; + memset(tx, 0, sizeof(btc_tx_t)); + tx->version = 1; } void btc_init_tx_in(btc_tx_in_t* tx_in) { @@ -257,70 +247,70 @@ in3_ret_t btc_tx_id(btc_tx_t* tx, bytes32_t dst) { return IN3_OK; } -// creates a raw unsigned transaction -// TODO: implement better error handling -// TODO: Support witnesses -void create_raw_tx(btc_tx_in_t* tx_in, uint32_t tx_in_len, btc_tx_out_t* tx_out, uint32_t tx_out_len, uint32_t lock_time, bytes_t* dst_raw_tx) { - if (!tx_in || !tx_out || !dst_raw_tx || tx_in_len == 0 || tx_out_len == 0) { - // TODO: Implement better error handling - printf("ERROR: arguments for creating a btc transaction can not be null\n"); - return; - } - btc_tx_t tx; - tx.version = 1; - tx.flag = 0; - tx.input_count = tx_in_len; - tx.output_count = tx_out_len; - tx.lock_time = lock_time; - - // Get inputs - // -- serialize inputs - bytes_t* serialized_inputs = malloc(tx_in_len * sizeof(bytes_t)); - uint32_t raw_input_size = 0; - for (uint32_t i = 0; i < tx_in_len; i++) { - btc_serialize_tx_in(&tx_in[i], &serialized_inputs[i]); - raw_input_size += serialized_inputs[i].len; - } - // -- Copy raw inputs into tx - tx.input.data = malloc(raw_input_size); - tx.input.len = raw_input_size; - uint32_t prev_input_len = 0; - for (uint32_t i = 0; i < tx_in_len; i++) { - for (uint32_t j = 0; j < serialized_inputs[i].len; j++) { - tx.input.data[j + prev_input_len] = serialized_inputs[i].data[j]; - } - prev_input_len = serialized_inputs[i].len; - } - - // Get Outputs - // -- serialize outputs - bytes_t* serialized_outputs = malloc(tx_out_len * sizeof(bytes_t)); - uint32_t raw_output_size = 0; - for (uint32_t i = 0; i < tx_out_len; i++) { - btc_serialize_tx_out(&tx_out[i], &serialized_outputs[i]); - raw_output_size += serialized_outputs[i].len; - } - // -- Copy raw outputs into tx - tx.output.data = malloc(raw_output_size); - tx.output.len = raw_output_size; - uint32_t prev_output_len = 0; - for (uint32_t i = 0; i < tx_out_len; i++) { - for (uint32_t j = 0; j < serialized_outputs[i].len; j++) { - tx.output.data[j + prev_output_len] = serialized_outputs[i].data[j]; - } - prev_output_len = serialized_outputs[i].len; - } - - // free buffers - for (uint32_t i = 0; i < tx_in_len; i++) { - _free(serialized_inputs[i].data); - } - _free(serialized_inputs); - for (uint32_t i = 0; i < tx_out_len; i++) { - _free(serialized_outputs[i].data); - } - _free(serialized_outputs); -} +// // creates a raw unsigned transaction +// // TODO: implement better error handling +// // TODO: Support witnesses +// void create_raw_tx(btc_tx_in_t* tx_in, uint32_t tx_in_len, btc_tx_out_t* tx_out, uint32_t tx_out_len, uint32_t lock_time, bytes_t* dst_raw_tx) { +// if (!tx_in || !tx_out || !dst_raw_tx || tx_in_len == 0 || tx_out_len == 0) { +// // TODO: Implement better error handling +// printf("ERROR: arguments for creating a btc transaction can not be null\n"); +// return; +// } +// btc_tx_t tx; +// tx.version = 1; +// tx.flag = 0; +// tx.input_count = tx_in_len; +// tx.output_count = tx_out_len; +// tx.lock_time = lock_time; + +// // Get inputs +// // -- serialize inputs +// bytes_t* serialized_inputs = malloc(tx_in_len * sizeof(bytes_t)); +// uint32_t raw_input_size = 0; +// for (uint32_t i = 0; i < tx_in_len; i++) { +// btc_serialize_tx_in(&tx_in[i], &serialized_inputs[i]); +// raw_input_size += serialized_inputs[i].len; +// } +// // -- Copy raw inputs into tx +// tx.input.data = malloc(raw_input_size); +// tx.input.len = raw_input_size; +// uint32_t prev_input_len = 0; +// for (uint32_t i = 0; i < tx_in_len; i++) { +// for (uint32_t j = 0; j < serialized_inputs[i].len; j++) { +// tx.input.data[j + prev_input_len] = serialized_inputs[i].data[j]; +// } +// prev_input_len = serialized_inputs[i].len; +// } + +// // Get Outputs +// // -- serialize outputs +// bytes_t* serialized_outputs = malloc(tx_out_len * sizeof(bytes_t)); +// uint32_t raw_output_size = 0; +// for (uint32_t i = 0; i < tx_out_len; i++) { +// btc_serialize_tx_out(&tx_out[i], &serialized_outputs[i]); +// raw_output_size += serialized_outputs[i].len; +// } +// // -- Copy raw outputs into tx +// tx.output.data = malloc(raw_output_size); +// tx.output.len = raw_output_size; +// uint32_t prev_output_len = 0; +// for (uint32_t i = 0; i < tx_out_len; i++) { +// for (uint32_t j = 0; j < serialized_outputs[i].len; j++) { +// tx.output.data[j + prev_output_len] = serialized_outputs[i].data[j]; +// } +// prev_output_len = serialized_outputs[i].len; +// } + +// // free buffers +// for (uint32_t i = 0; i < tx_in_len; i++) { +// _free(serialized_inputs[i].data); +// } +// _free(serialized_inputs); +// for (uint32_t i = 0; i < tx_out_len; i++) { +// _free(serialized_outputs[i].data); +// } +// _free(serialized_outputs); +// } void add_to_tx(btc_tx_t* tx, void* src, btc_tx_field_t field_type) { if (!tx || !src) { @@ -332,13 +322,13 @@ void add_to_tx(btc_tx_t* tx, void* src, btc_tx_field_t field_type) { uint32_t old_len; switch (field_type) { - case INPUT: + case BTC_INPUT: btc_serialize_tx_in((btc_tx_in_t*) src, &raw_src); old_len = tx->input.len; dst = &tx->input; tx->input_count++; break; - case OUTPUT: + case BTC_OUTPUT: btc_serialize_tx_out((btc_tx_out_t*) src, &raw_src); old_len = tx->output.len; dst = &tx->output; @@ -361,9 +351,61 @@ void add_to_tx(btc_tx_t* tx, void* src, btc_tx_field_t field_type) { } void add_input_to_tx(btc_tx_t* tx, btc_tx_in_t* tx_in) { - add_to_tx(tx, tx_in, INPUT); + add_to_tx(tx, tx_in, BTC_INPUT); } void add_output_to_tx(btc_tx_t* tx, btc_tx_out_t* tx_out) { - add_to_tx(tx, tx_out, OUTPUT); -} \ No newline at end of file + add_to_tx(tx, tx_out, BTC_OUTPUT); +} + +void add_outputs_to_tx(d_token_t* outputs, btc_tx_t* tx) { + uint32_t len = d_len(outputs); + for (uint32_t i = 0; i < len; i++) { + d_token_t* output = d_get_at(outputs, i); + + const char* script_string = d_string(d_get(output, key("script"))); + uint64_t value = d_get_long(d_get(output, key("value")), 0L); + + btc_tx_out_t tx_out; + uint32_t script_len = strlen(script_string) / 2; + bytes_t script = bytes(_malloc(script_len), script_len); + hex_to_bytes(script_string, strlen(script_string), script.data, script.len); + + tx_out.script = script; + tx_out.value = value; + + add_output_to_tx(tx, &tx_out); + } +} + +// utxos must be freed +uint32_t btc_prepare_utxo(d_token_t* utxo_inputs, btc_utxo_t** utxos) { + uint32_t len = d_len(utxo_inputs); + *utxos = _malloc(len * sizeof(btc_utxo_t)); + + for (uint32_t i = 0; i < len; i++) { + btc_utxo_t utxo; + d_token_t* utxo_input = d_get_at(utxo_inputs, i); + uint32_t tx_index = d_get_long(d_get(utxo_input, key("tx_index")), 0L); + uint64_t value = d_get_long(d_get(utxo_input, key("value")), 0L); + const char* tx_hash_string = d_string(d_get(utxo_input, key("tx_hash"))); + const char* tx_script_string = d_string(d_get(utxo_input, key("script"))); + + uint32_t tx_hash_len = strlen(tx_hash_string) / 2; + bytes_t tx_hash = bytes(_malloc(tx_hash_len), tx_hash_len); + hex_to_bytes(tx_hash_string, strlen(tx_hash_string), tx_hash.data, tx_hash.len); + + uint32_t tx_script_len = strlen(tx_script_string) / 2; + bytes_t tx_script = bytes(_malloc(tx_script_len), tx_script_len); + hex_to_bytes(tx_script_string, strlen(tx_script_string), tx_script.data, tx_script.len); + + utxo.tx_hash = tx_hash.data; + utxo.tx_index = tx_index; + utxo.tx_out.value = value; + utxo.tx_out.script = tx_script; + + *utxos[i] = utxo; + } + + return len; +} diff --git a/c/src/verifier/btc/btc_types.h b/c/src/verifier/btc/btc_types.h index 423f7cadc..b05e436a7 100644 --- a/c/src/verifier/btc/btc_types.h +++ b/c/src/verifier/btc/btc_types.h @@ -60,4 +60,9 @@ static inline bool btc_is_witness(bytes_t tx) { return tx.data[4] == 0 && tx.data[5] == 1; } +void add_outputs_to_tx(d_token_t* outputs, btc_tx_t* tx); +uint32_t btc_prepare_utxo(d_token_t* utxo_inputs, btc_utxo_t** utxos); + +// void create_raw_tx(btc_tx_in_t* tx_in, uint32_t tx_in_len, btc_tx_out_t* tx_out, uint32_t tx_out_len, uint32_t lock_time, bytes_t* dst_raw_tx); + #endif \ No newline at end of file diff --git a/c/src/verifier/btc/rpc.yml b/c/src/verifier/btc/rpc.yml index 1c0029e7c..1cd20d7ef 100644 --- a/c/src/verifier/btc/rpc.yml +++ b/c/src/verifier/btc/rpc.yml @@ -1,4 +1,39 @@ types: + the value: + script: + descr: the script + type: string + value: + descr: the value + type: long + utxo: + tx_index: + descr: the transaction index that this utxo refers to + type: uint + value: + descr: the value + type: long + tx_hash: + descr: the transaction hash (same as provided) + type: string + script: + descr: the script + type: string + + output: + tx_index: + descr: the block hash (same as provided) + type: uint + value: + descr: the block hash (same as provided) + type: long + tx_hash: + descr: the block hash (same as provided) + type: string + script: + descr: the block hash (same as provided) + type: string + btcblockheader: hash: descr: the block hash (same as provided) @@ -793,8 +828,6 @@ btc: cbtx: "0x02000000000101000000000000000000000000000000000000000...000000" cbtxMerkleProof: "0xa3d607b274770911e53f06dbdb76440580ff968239...0ba297" - - getdifficulty: descr: Returns the proof-of-work difficulty as a multiple of the minimum difficulty. in3Params: @@ -995,7 +1028,6 @@ btc: cbtx: 0x01000000...cf6e8f930acb8f38b588d76cd8c3da3258d5a7...000000 cbtxMerkleProof: 0x25575bcaf3e11970ccf835e88d6f97bedd6b85...bfdf46 - getbestblockhash: descr: Returns the hash of the best (tip) block in the longest blockchain. in3Params: @@ -1038,7 +1070,29 @@ btc: final: "0x00008020f61dfcc47a6daed717b12221855196dee02d844ebb9c...774f4c" cbtx: "0x02000000000101000000000000000000000000000000000000000...000000" cbtxMerkleProof: "0xa3d607b274770911e53f06dbdb76440580ff968239...0ba297" - - - - + sendtransaction: + descr: sends a transaction to a btc node + params: + from: + descr: the public key derived from the private key used to sign + type: string + outputs: + descr: the desired outputs of the transaction + type: output + array: true + utxo: + descr: the utxo used to proove liquidity for the transaction + type: utxo + array: true + result: + descr: the transactionhash + type: bytes32 + sendrawtransaction: + descr: sends a transaction to a btc node + params: + transaction: + descr: the signed raw transaction + type: string + result: + descr: the transactionhash + type: bytes32 From 039a1eafb8cec567e27ccfb7e12e7a9b0c2086e5 Mon Sep 17 00:00:00 2001 From: leonardotc Date: Fri, 29 Oct 2021 19:10:05 +0200 Subject: [PATCH 088/101] Add btc sendtransaction to btc rpc --- c/src/verifier/btc/btc.c | 107 +++++++++++------ c/src/verifier/btc/btc_sign.c | 57 ++++----- c/src/verifier/btc/btc_sign.h | 6 +- c/src/verifier/btc/btc_types.c | 210 ++++++++++++++++++++------------- c/src/verifier/btc/btc_types.h | 5 + c/src/verifier/btc/rpc.yml | 68 +++++++++-- 6 files changed, 294 insertions(+), 159 deletions(-) diff --git a/c/src/verifier/btc/btc.c b/c/src/verifier/btc/btc.c index bdf92d0d4..f05bb8e00 100644 --- a/c/src/verifier/btc/btc.c +++ b/c/src/verifier/btc/btc.c @@ -8,6 +8,7 @@ #include "../../verifier/eth1/nano/eth_nano.h" #include "btc_merkle.h" #include "btc_serialize.h" +#include "btc_sign.h" #include "btc_target.h" #include "btc_types.h" #include @@ -517,43 +518,6 @@ static in3_ret_t in3_verify_btc(btc_target_conf_t* conf, in3_vctx_t* vc) { // } // #endif -#if !defined(RPC_ONLY) || defined(RPC_SENDTRANSACTION) - - // SERVER: sendtransaction(raw_signed_tx) - if (VERIFY_RPC("sendtransaction")) { - REQUIRE_EXPERIMENTAL(vc->req, "btc") - // This is the RPC that abstracts most of what is done in the background before sending a transaction: - // Get outputs we want to send - d_token_t* outputs = d_get_at(params, 0); - d_token_t* utxo_list = d_get_at(params, 1); - // select "best" set of UTXOs - // btc_utxo_t* utxo_list = NULL; - uint32_t miner_fee = 0, outputs_total = 0, utxo_total = 0; - // ---- select utxos here - // create output for receiving the transaction "change", discounting miner fee - btc_tx_out_t tx_out_change; - btc_init_tx_out(&tx_out_change); - tx_out_change.value = utxo_total - miner_fee - outputs_total; - // create raw unsigned transaction using selected set of utxos (inputs) and outputs (both received in Command Line and created "change") - // Obtain private key - // Sign previously obtained unsigned transaction using private key - // Send transaction to in3 server - // return succes (transaction hash, so the user can look for it online) or error code - } -#endif - -#if !defined(RPC_ONLY) || defined(RPC_BUILDUNSIGNEDTRANSACTION) - - if (VERIFY_RPC("buildunsignedtransaction")) { - REQUIRE_EXPERIMENTAL(vc->req, "btc") - // Get inputs list - // Get outputs list - // Get other important parameters (witnesses, tx_type (ex: p2pk), fees, sighash_type, etc.) - // Build the unsigned transaction - // return raw unsigned transaction - } -#endif - #if !defined(RPC_ONLY) || defined(RPC_SIGNTRANSACTION) if (VERIFY_RPC("signtransaction")) { @@ -578,6 +542,71 @@ static in3_ret_t in3_verify_btc(btc_target_conf_t* conf, in3_vctx_t* vc) { return IN3_EIGNORE; } +in3_ret_t send_transaction(btc_target_conf_t* conf, in3_rpc_handle_ctx_t* ctx) { + UNUSED_VAR(conf); + + in3_req_t* req = ctx->req; + // This is the RPC that abstracts most of what is done in the background before sending a transaction: + // Get outputs we want to send + d_token_t* params = ctx->params; + bytes_t pub_key; + pub_key.len = 20; + TRY_PARAM_GET_REQUIRED_ADDRESS(pub_key.data, ctx, 0) + d_token_t* outputs = d_get_at(params, 1); + d_token_t* utxo_list = d_get_at(params, 2); + + // select "best" set of UTXOs + // btc_utxo_t* utxo_list = NULL; + uint32_t miner_fee = 0, outputs_total = 0, utxo_total = 0; + // ---- select utxos here + // create output for receiving the transaction "change", discounting miner fee + btc_tx_out_t tx_out_change; + btc_init_tx_out(&tx_out_change); + tx_out_change.value = utxo_total - miner_fee - outputs_total; + // create raw unsigned transaction using selected set of utxos (inputs) and outputs (both received in Command Line and created "change") + + // {"method":"sendrawtransaction", "params":["0100000001f90c6776e0aff73fdc67d57beadc283cea8c63cc7b8d48249bd79ce6a7823fc0000000008a47304402201955addf93c52fe20ce468603e97d3ea495c3072d3ebe92120ad0a200abbb51902204a9fe8e85fcee5621fc902796bbdf7ce490dc06cbfe7acb37eeb2f8c9406710e0141046d6caac248af96f6afa7f904f550253a0f3ef3f5aa2fe6838a95b216691468e2487e6222a6664e079c8edf7518defd562dbeda1e7593dfd7f0be285880a24dabffffffff01e803000000000000015100000000"]} + + bytes_t signed_tx = NULL_BYTES; + btc_tx_t tx; + btc_init_tx(&tx); + add_outputs_to_tx(outputs, &tx); + + btc_utxo_t* selected_utxo_list = NULL; + uint32_t utxo_list_len = btc_prepare_utxo(utxo_list, &selected_utxo_list); + // TODO: prepare tx + TRY(btc_sign_tx(ctx->req, &tx, selected_utxo_list, utxo_list_len, &pub_key)); + + btc_serialize_tx(&tx, &signed_tx); + sb_t sb = {0}; + sb_add_rawbytes(&sb, "\"", signed_tx, 0); + sb_add_chars(&sb, "\""); + + // now that we included the signature in the rpc-request, we can free it + the old rpc-request. + _free(signed_tx.data); + + d_token_t* result = NULL; + TRY_FINAL(req_send_sub_request(req, "sendrawtransaction", sb.data, NULL, &result, NULL), _free(sb.data)); + sb_add_json(in3_rpc_handle_start(ctx), "", result); + return in3_rpc_handle_finish(ctx); +} + +static in3_ret_t btc_handle_intern(btc_target_conf_t* conf, in3_rpc_handle_ctx_t* ctx) { + in3_req_t* req = ctx->req; + // we only handle BTC + if (req->client->chain.type != CHAIN_BTC) return IN3_EIGNORE; + + // make sure the conf is filled with data from the cache + btc_check_conf(req->client, conf); + +#if !defined(RPC_ONLY) || defined(RPC_SENDTRANSACTION) + + // SERVER: sendtransaction(raw_signed_tx) + TRY_RPC("sendtransaction", send_transaction(conf, ctx)) +#endif + return IN3_EIGNORE; +} + static in3_ret_t handle_btc(void* pdata, in3_plugin_act_t action, void* pctx) { btc_target_conf_t* conf = pdata; switch (action) { @@ -604,6 +633,8 @@ static in3_ret_t handle_btc(void* pdata, in3_plugin_act_t action, void* pctx) { return IN3_EIGNORE; return IN3_OK; } + case PLGN_ACT_RPC_HANDLE: + return btc_handle_intern(conf, pctx); case PLGN_ACT_RPC_VERIFY: return in3_verify_btc(conf, pctx); default: @@ -618,7 +649,7 @@ in3_ret_t in3_register_btc(in3_t* c) { tc->max_daps = 20; tc->max_diff = 10; tc->dap_limit = 20; - return in3_plugin_register(c, PLGN_ACT_RPC_VERIFY | PLGN_ACT_TERM | PLGN_ACT_CONFIG_GET | PLGN_ACT_CONFIG_SET, handle_btc, tc, false); + return in3_plugin_register(c, PLGN_ACT_RPC_VERIFY | PLGN_ACT_TERM | PLGN_ACT_CONFIG_GET | PLGN_ACT_CONFIG_SET | PLGN_ACT_RPC_HANDLE, handle_btc, tc, false); } /* static void print_hex(char* prefix, uint8_t* data, int len) { diff --git a/c/src/verifier/btc/btc_sign.c b/c/src/verifier/btc/btc_sign.c index 88172efe9..8f083e807 100644 --- a/c/src/verifier/btc/btc_sign.c +++ b/c/src/verifier/btc/btc_sign.c @@ -1,4 +1,7 @@ #include "btc_sign.h" +#include "../../core/client/plugin.h" +#include "../../core/client/request.h" +#include "../../core/client/request_internal.h" #include "../../third-party/crypto/secp256k1.h" #include "btc_serialize.h" #include "btc_types.h" @@ -25,28 +28,23 @@ static void prepare_tx_in(const btc_utxo_t* utxo, btc_tx_in_t* tx_in) { } // WARNING: You need to free tx_in->script.data after calling this function! -void btc_sign_tx_in(const btc_tx_t* tx, const btc_utxo_t* utxo_list, const uint32_t utxo_index, const bytes_t* priv_key, btc_tx_in_t* tx_in, uint8_t sighash) { - if (!tx_in || !priv_key) { - // TODO: Implement better error handling - printf("ERROR: in btc_sign_tx_in: function arguments cannot be NULL."); - return; +in3_ret_t btc_sign_tx_in(in3_req_t* req, const btc_tx_t* tx, const btc_utxo_t* utxo_list, const uint32_t utxo_index, const bytes_t* pub_key, btc_tx_in_t* tx_in, uint8_t sighash) { + if (!tx_in || !pub_key) { + return req_set_error(req, "ERROR: in btc_sign_tx_in: function arguments cannot be NULL.", IN3_ERPC); } // TODO: Implement support for other sighashes if (sighash != BTC_SIGHASH_ALL) { - printf("ERROR: in btc_sign_tx_in: Sighash not supported."); - return; + return req_set_error(req, "ERROR: in btc_sign_tx_in: Sighash not supported.", IN3_ERPC); } // Generate an unsigned transaction. This will be used to henerate the hash provided to // the ecdsa signing algorithm btc_tx_t tmp_tx; - tmp_tx.version = tx->version; - tmp_tx.flag = 0; // TODO: Implement segwit support - tmp_tx.input_count = 0; - tmp_tx.output_count = tx->output_count; - tmp_tx.output.len = tx->output.len; - tmp_tx.output.data = alloca(sizeof(uint8_t) * tmp_tx.output.len); - tmp_tx.witnesses.len = 0; + btc_init_tx(&tmp_tx); + tmp_tx.version = tx->version; + tmp_tx.output_count = tx->output_count; + tmp_tx.output.len = tx->output.len; + tmp_tx.output.data = alloca(sizeof(uint8_t) * tmp_tx.output.len); for (uint32_t i = 0; i < tmp_tx.output.len; i++) tmp_tx.output.data[i] = tx->output.data[i]; tmp_tx.lock_time = tx->lock_time; @@ -71,7 +69,7 @@ void btc_sign_tx_in(const btc_tx_t* tx, const btc_utxo_t* utxo_list, const uint3 btc_serialize_tx(&tmp_tx, &(tmp_tx.all)); bytes_t hash_input; hash_input.len = tmp_tx.all.len + 4; - hash_input.data = malloc(hash_input.len * sizeof(uint8_t)); + hash_input.data = alloca(hash_input.len * sizeof(uint8_t)); // TODO: Implement this in a more efficient way. Right now we copy // the whole tx just to add 4 bytes at the end of the stream @@ -85,17 +83,18 @@ void btc_sign_tx_in(const btc_tx_t* tx, const btc_utxo_t* utxo_list, const uint3 // Finally, sign transaction input // -- Obtain DER signature - uint8_t sig[65]; + bytes_t sig; + sig.data = NULL; + sig.len = 65; + bytes_t der_sig; der_sig.data = alloca(sizeof(uint8_t) * 75); - ecdsa_sign(&secp256k1, HASHER_SHA2D, priv_key->data, hash_input.data, hash_input.len, sig, sig + 64, NULL); - der_sig.len = ecdsa_sig_to_der(sig, der_sig.data); - der_sig.data[der_sig.len++] = sig[64]; // append verification byte to end of DER signature - // -- Extract public key out of the provided private key. This will be used to build the tx_in scriptSig - uint8_t pub_key[65]; - ecdsa_get_public_key65(&secp256k1, (const uint8_t*) priv_key->data, pub_key); + TRY(req_require_signature(req, SIGN_EC_BTC, PL_SIGN_BTCTX, &sig, hash_input, *pub_key, req->requests[0])) + + der_sig.len = ecdsa_sig_to_der(sig.data, der_sig.data); + der_sig.data[der_sig.len++] = sig.data[64]; // append verification byte to end of DER signature // -- build scriptSig: DER_LEN|DER_SIG|PUB_KEY_LEN|PUB_BEY uint32_t scriptsig_len = der_sig.len + 1 + 65; // DER_SIG + 1 byte PUBKEY_LEN + PUBKEY @@ -116,26 +115,30 @@ void btc_sign_tx_in(const btc_tx_t* tx, const btc_utxo_t* utxo_list, const uint3 // write pubkey i = 0; while (i < 65) { - b->data[index++] = pub_key[i++]; + b->data[index++] = pub_key->data[i++]; } // signature is complete _free(tmp_tx.all.data); _free(tmp_tx.input.data); - _free(hash_input.data); + // _free(hash_input.data); + + return IN3_OK; } -void btc_sign_tx(btc_tx_t* tx, const btc_utxo_t* selected_utxo_list, uint32_t utxo_list_len, bytes_t* priv_key) { +in3_ret_t btc_sign_tx(in3_req_t* req, btc_tx_t* tx, const btc_utxo_t* selected_utxo_list, uint32_t utxo_list_len, bytes_t* pub_key) { // for each input in a tx: for (uint32_t i = 0; i < utxo_list_len; i++) { // -- for each pub_key (assume we only have one pub key for now): // TODO: Allow setting a specific pub_key for each input btc_tx_in_t tx_in; prepare_tx_in(&selected_utxo_list[i], &tx_in); - btc_sign_tx_in(tx, selected_utxo_list, i, priv_key, &tx_in, BTC_SIGHASH_ALL); + TRY_CATCH(btc_sign_tx_in(req, tx, selected_utxo_list, i, pub_key, &tx_in, BTC_SIGHASH_ALL), + _free(tx_in.script.data); + _free(tx_in.prev_tx_hash);) add_input_to_tx(tx, &tx_in); _free(tx_in.script.data); _free(tx_in.prev_tx_hash); } - return; + return IN3_OK; } \ No newline at end of file diff --git a/c/src/verifier/btc/btc_sign.h b/c/src/verifier/btc/btc_sign.h index e819441c5..f9c188552 100644 --- a/c/src/verifier/btc/btc_sign.h +++ b/c/src/verifier/btc/btc_sign.h @@ -1,6 +1,7 @@ #ifndef _BTC_SIGN_H #define _BTC_SIGN_H +#include "../../core/client/request.h" #include "btc_types.h" #define BTC_SIGHASH_ALL 0x1 @@ -8,8 +9,7 @@ #define BTC_SIGHASH_SINGLE 0x3 #define BTC_SIGHASH_ANYONECANPAY 0x80 -void create_raw_tx(btc_tx_in_t* tx_in, uint32_t tx_in_len, btc_tx_out_t* tx_out, uint32_t tx_out_len, uint32_t lock_time, bytes_t* dst_raw_tx); -void btc_sign_tx_in(const btc_tx_t* tx, const btc_utxo_t* utxo_list, const uint32_t utxo_index, const bytes_t* priv_key, btc_tx_in_t* tx_in, uint8_t sighash); -void btc_sign_tx(btc_tx_t* tx, const btc_utxo_t* selected_utxo_list, uint32_t utxo_list_len, bytes_t* priv_key); +in3_ret_t btc_sign_tx_in(in3_req_t* ctx, const btc_tx_t* tx, const btc_utxo_t* utxo_list, const uint32_t utxo_index, const bytes_t* pub_key, btc_tx_in_t* tx_in, uint8_t sighash); +in3_ret_t btc_sign_tx(in3_req_t* ctx, btc_tx_t* tx, const btc_utxo_t* selected_utxo_list, uint32_t utxo_list_len, bytes_t* pub_key); #endif \ No newline at end of file diff --git a/c/src/verifier/btc/btc_types.c b/c/src/verifier/btc/btc_types.c index a399547bb..e0001946b 100644 --- a/c/src/verifier/btc/btc_types.c +++ b/c/src/verifier/btc/btc_types.c @@ -1,5 +1,6 @@ #include "btc_types.h" #include "../../core/util/mem.h" +#include "../../core/util/utils.h" #include "btc_serialize.h" // Transaction fixed size values @@ -14,24 +15,13 @@ #define BTC_TX_OUT_VALUE_SIZE_BYTES 8 typedef enum btc_tx_field { - INPUT, - OUTPUT + BTC_INPUT, + BTC_OUTPUT } btc_tx_field_t; void btc_init_tx(btc_tx_t* tx) { - tx->all.len = 0; - tx->all.data = NULL; - tx->version = 1; - tx->flag = 0; - tx->input_count = 0; - tx->output_count = 0; - tx->input.len = 0; - tx->input.data = NULL; - tx->output.len = 0; - tx->output.data = NULL; - tx->witnesses.len = 0; - tx->witnesses.data = NULL; - tx->lock_time = 0; + memset(tx, 0, sizeof(btc_tx_t)); + tx->version = 1; } void btc_init_tx_in(btc_tx_in_t* tx_in) { @@ -257,70 +247,70 @@ in3_ret_t btc_tx_id(btc_tx_t* tx, bytes32_t dst) { return IN3_OK; } -// creates a raw unsigned transaction -// TODO: implement better error handling -// TODO: Support witnesses -void create_raw_tx(btc_tx_in_t* tx_in, uint32_t tx_in_len, btc_tx_out_t* tx_out, uint32_t tx_out_len, uint32_t lock_time, bytes_t* dst_raw_tx) { - if (!tx_in || !tx_out || !dst_raw_tx || tx_in_len == 0 || tx_out_len == 0) { - // TODO: Implement better error handling - printf("ERROR: arguments for creating a btc transaction can not be null\n"); - return; - } - btc_tx_t tx; - tx.version = 1; - tx.flag = 0; - tx.input_count = tx_in_len; - tx.output_count = tx_out_len; - tx.lock_time = lock_time; - - // Get inputs - // -- serialize inputs - bytes_t* serialized_inputs = malloc(tx_in_len * sizeof(bytes_t)); - uint32_t raw_input_size = 0; - for (uint32_t i = 0; i < tx_in_len; i++) { - btc_serialize_tx_in(&tx_in[i], &serialized_inputs[i]); - raw_input_size += serialized_inputs[i].len; - } - // -- Copy raw inputs into tx - tx.input.data = malloc(raw_input_size); - tx.input.len = raw_input_size; - uint32_t prev_input_len = 0; - for (uint32_t i = 0; i < tx_in_len; i++) { - for (uint32_t j = 0; j < serialized_inputs[i].len; j++) { - tx.input.data[j + prev_input_len] = serialized_inputs[i].data[j]; - } - prev_input_len = serialized_inputs[i].len; - } - - // Get Outputs - // -- serialize outputs - bytes_t* serialized_outputs = malloc(tx_out_len * sizeof(bytes_t)); - uint32_t raw_output_size = 0; - for (uint32_t i = 0; i < tx_out_len; i++) { - btc_serialize_tx_out(&tx_out[i], &serialized_outputs[i]); - raw_output_size += serialized_outputs[i].len; - } - // -- Copy raw outputs into tx - tx.output.data = malloc(raw_output_size); - tx.output.len = raw_output_size; - uint32_t prev_output_len = 0; - for (uint32_t i = 0; i < tx_out_len; i++) { - for (uint32_t j = 0; j < serialized_outputs[i].len; j++) { - tx.output.data[j + prev_output_len] = serialized_outputs[i].data[j]; - } - prev_output_len = serialized_outputs[i].len; - } - - // free buffers - for (uint32_t i = 0; i < tx_in_len; i++) { - _free(serialized_inputs[i].data); - } - _free(serialized_inputs); - for (uint32_t i = 0; i < tx_out_len; i++) { - _free(serialized_outputs[i].data); - } - _free(serialized_outputs); -} +// // creates a raw unsigned transaction +// // TODO: implement better error handling +// // TODO: Support witnesses +// void create_raw_tx(btc_tx_in_t* tx_in, uint32_t tx_in_len, btc_tx_out_t* tx_out, uint32_t tx_out_len, uint32_t lock_time, bytes_t* dst_raw_tx) { +// if (!tx_in || !tx_out || !dst_raw_tx || tx_in_len == 0 || tx_out_len == 0) { +// // TODO: Implement better error handling +// printf("ERROR: arguments for creating a btc transaction can not be null\n"); +// return; +// } +// btc_tx_t tx; +// tx.version = 1; +// tx.flag = 0; +// tx.input_count = tx_in_len; +// tx.output_count = tx_out_len; +// tx.lock_time = lock_time; + +// // Get inputs +// // -- serialize inputs +// bytes_t* serialized_inputs = malloc(tx_in_len * sizeof(bytes_t)); +// uint32_t raw_input_size = 0; +// for (uint32_t i = 0; i < tx_in_len; i++) { +// btc_serialize_tx_in(&tx_in[i], &serialized_inputs[i]); +// raw_input_size += serialized_inputs[i].len; +// } +// // -- Copy raw inputs into tx +// tx.input.data = malloc(raw_input_size); +// tx.input.len = raw_input_size; +// uint32_t prev_input_len = 0; +// for (uint32_t i = 0; i < tx_in_len; i++) { +// for (uint32_t j = 0; j < serialized_inputs[i].len; j++) { +// tx.input.data[j + prev_input_len] = serialized_inputs[i].data[j]; +// } +// prev_input_len = serialized_inputs[i].len; +// } + +// // Get Outputs +// // -- serialize outputs +// bytes_t* serialized_outputs = malloc(tx_out_len * sizeof(bytes_t)); +// uint32_t raw_output_size = 0; +// for (uint32_t i = 0; i < tx_out_len; i++) { +// btc_serialize_tx_out(&tx_out[i], &serialized_outputs[i]); +// raw_output_size += serialized_outputs[i].len; +// } +// // -- Copy raw outputs into tx +// tx.output.data = malloc(raw_output_size); +// tx.output.len = raw_output_size; +// uint32_t prev_output_len = 0; +// for (uint32_t i = 0; i < tx_out_len; i++) { +// for (uint32_t j = 0; j < serialized_outputs[i].len; j++) { +// tx.output.data[j + prev_output_len] = serialized_outputs[i].data[j]; +// } +// prev_output_len = serialized_outputs[i].len; +// } + +// // free buffers +// for (uint32_t i = 0; i < tx_in_len; i++) { +// _free(serialized_inputs[i].data); +// } +// _free(serialized_inputs); +// for (uint32_t i = 0; i < tx_out_len; i++) { +// _free(serialized_outputs[i].data); +// } +// _free(serialized_outputs); +// } void add_to_tx(btc_tx_t* tx, void* src, btc_tx_field_t field_type) { if (!tx || !src) { @@ -332,13 +322,13 @@ void add_to_tx(btc_tx_t* tx, void* src, btc_tx_field_t field_type) { uint32_t old_len; switch (field_type) { - case INPUT: + case BTC_INPUT: btc_serialize_tx_in((btc_tx_in_t*) src, &raw_src); old_len = tx->input.len; dst = &tx->input; tx->input_count++; break; - case OUTPUT: + case BTC_OUTPUT: btc_serialize_tx_out((btc_tx_out_t*) src, &raw_src); old_len = tx->output.len; dst = &tx->output; @@ -361,9 +351,61 @@ void add_to_tx(btc_tx_t* tx, void* src, btc_tx_field_t field_type) { } void add_input_to_tx(btc_tx_t* tx, btc_tx_in_t* tx_in) { - add_to_tx(tx, tx_in, INPUT); + add_to_tx(tx, tx_in, BTC_INPUT); } void add_output_to_tx(btc_tx_t* tx, btc_tx_out_t* tx_out) { - add_to_tx(tx, tx_out, OUTPUT); -} \ No newline at end of file + add_to_tx(tx, tx_out, BTC_OUTPUT); +} + +void add_outputs_to_tx(d_token_t* outputs, btc_tx_t* tx) { + uint32_t len = d_len(outputs); + for (uint32_t i = 0; i < len; i++) { + d_token_t* output = d_get_at(outputs, i); + + const char* script_string = d_string(d_get(output, key("script"))); + uint64_t value = d_get_long(d_get(output, key("value")), 0L); + + btc_tx_out_t tx_out; + uint32_t script_len = strlen(script_string) / 2; + bytes_t script = bytes(_malloc(script_len), script_len); + hex_to_bytes(script_string, strlen(script_string), script.data, script.len); + + tx_out.script = script; + tx_out.value = value; + + add_output_to_tx(tx, &tx_out); + } +} + +// utxos must be freed +uint32_t btc_prepare_utxo(d_token_t* utxo_inputs, btc_utxo_t** utxos) { + uint32_t len = d_len(utxo_inputs); + *utxos = _malloc(len * sizeof(btc_utxo_t)); + + for (uint32_t i = 0; i < len; i++) { + btc_utxo_t utxo; + d_token_t* utxo_input = d_get_at(utxo_inputs, i); + uint32_t tx_index = d_get_long(d_get(utxo_input, key("tx_index")), 0L); + uint64_t value = d_get_long(d_get(utxo_input, key("value")), 0L); + const char* tx_hash_string = d_string(d_get(utxo_input, key("tx_hash"))); + const char* tx_script_string = d_string(d_get(utxo_input, key("script"))); + + uint32_t tx_hash_len = strlen(tx_hash_string) / 2; + bytes_t tx_hash = bytes(_malloc(tx_hash_len), tx_hash_len); + hex_to_bytes(tx_hash_string, strlen(tx_hash_string), tx_hash.data, tx_hash.len); + + uint32_t tx_script_len = strlen(tx_script_string) / 2; + bytes_t tx_script = bytes(_malloc(tx_script_len), tx_script_len); + hex_to_bytes(tx_script_string, strlen(tx_script_string), tx_script.data, tx_script.len); + + utxo.tx_hash = tx_hash.data; + utxo.tx_index = tx_index; + utxo.tx_out.value = value; + utxo.tx_out.script = tx_script; + + *utxos[i] = utxo; + } + + return len; +} diff --git a/c/src/verifier/btc/btc_types.h b/c/src/verifier/btc/btc_types.h index 423f7cadc..b05e436a7 100644 --- a/c/src/verifier/btc/btc_types.h +++ b/c/src/verifier/btc/btc_types.h @@ -60,4 +60,9 @@ static inline bool btc_is_witness(bytes_t tx) { return tx.data[4] == 0 && tx.data[5] == 1; } +void add_outputs_to_tx(d_token_t* outputs, btc_tx_t* tx); +uint32_t btc_prepare_utxo(d_token_t* utxo_inputs, btc_utxo_t** utxos); + +// void create_raw_tx(btc_tx_in_t* tx_in, uint32_t tx_in_len, btc_tx_out_t* tx_out, uint32_t tx_out_len, uint32_t lock_time, bytes_t* dst_raw_tx); + #endif \ No newline at end of file diff --git a/c/src/verifier/btc/rpc.yml b/c/src/verifier/btc/rpc.yml index 1c0029e7c..1cd20d7ef 100644 --- a/c/src/verifier/btc/rpc.yml +++ b/c/src/verifier/btc/rpc.yml @@ -1,4 +1,39 @@ types: + the value: + script: + descr: the script + type: string + value: + descr: the value + type: long + utxo: + tx_index: + descr: the transaction index that this utxo refers to + type: uint + value: + descr: the value + type: long + tx_hash: + descr: the transaction hash (same as provided) + type: string + script: + descr: the script + type: string + + output: + tx_index: + descr: the block hash (same as provided) + type: uint + value: + descr: the block hash (same as provided) + type: long + tx_hash: + descr: the block hash (same as provided) + type: string + script: + descr: the block hash (same as provided) + type: string + btcblockheader: hash: descr: the block hash (same as provided) @@ -793,8 +828,6 @@ btc: cbtx: "0x02000000000101000000000000000000000000000000000000000...000000" cbtxMerkleProof: "0xa3d607b274770911e53f06dbdb76440580ff968239...0ba297" - - getdifficulty: descr: Returns the proof-of-work difficulty as a multiple of the minimum difficulty. in3Params: @@ -995,7 +1028,6 @@ btc: cbtx: 0x01000000...cf6e8f930acb8f38b588d76cd8c3da3258d5a7...000000 cbtxMerkleProof: 0x25575bcaf3e11970ccf835e88d6f97bedd6b85...bfdf46 - getbestblockhash: descr: Returns the hash of the best (tip) block in the longest blockchain. in3Params: @@ -1038,7 +1070,29 @@ btc: final: "0x00008020f61dfcc47a6daed717b12221855196dee02d844ebb9c...774f4c" cbtx: "0x02000000000101000000000000000000000000000000000000000...000000" cbtxMerkleProof: "0xa3d607b274770911e53f06dbdb76440580ff968239...0ba297" - - - - + sendtransaction: + descr: sends a transaction to a btc node + params: + from: + descr: the public key derived from the private key used to sign + type: string + outputs: + descr: the desired outputs of the transaction + type: output + array: true + utxo: + descr: the utxo used to proove liquidity for the transaction + type: utxo + array: true + result: + descr: the transactionhash + type: bytes32 + sendrawtransaction: + descr: sends a transaction to a btc node + params: + transaction: + descr: the signed raw transaction + type: string + result: + descr: the transactionhash + type: bytes32 From 7a6feeeb655b1a0c6ebcd393b0950b584786313e Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Sat, 30 Oct 2021 11:16:38 +0200 Subject: [PATCH 089/101] fix includes --- c/src/verifier/btc/btc_sign.h | 1 + 1 file changed, 1 insertion(+) diff --git a/c/src/verifier/btc/btc_sign.h b/c/src/verifier/btc/btc_sign.h index e725df6ee..3db447fc6 100644 --- a/c/src/verifier/btc/btc_sign.h +++ b/c/src/verifier/btc/btc_sign.h @@ -1,6 +1,7 @@ #ifndef _BTC_SIGN_H #define _BTC_SIGN_H +#include "../../core/client/plugin.h" #include "btc_types.h" #define BTC_SIGHASH_ALL 0x1 From fbaf5141e3048c9ca06a94a8963e21fa2cae156c Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Sat, 30 Oct 2021 11:31:25 +0200 Subject: [PATCH 090/101] change type --- c/src/verifier/btc/rpc.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/c/src/verifier/btc/rpc.yml b/c/src/verifier/btc/rpc.yml index 1cd20d7ef..1c820a3b2 100644 --- a/c/src/verifier/btc/rpc.yml +++ b/c/src/verifier/btc/rpc.yml @@ -5,14 +5,14 @@ types: type: string value: descr: the value - type: long + type: uint64 utxo: tx_index: descr: the transaction index that this utxo refers to type: uint value: descr: the value - type: long + type: uint64 tx_hash: descr: the transaction hash (same as provided) type: string From d1d609de0273a3d1c08de86c805d3a5e49870842 Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Sat, 30 Oct 2021 11:32:04 +0200 Subject: [PATCH 091/101] fixed types --- c/src/verifier/btc/rpc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/c/src/verifier/btc/rpc.yml b/c/src/verifier/btc/rpc.yml index 1c820a3b2..aa5fe9632 100644 --- a/c/src/verifier/btc/rpc.yml +++ b/c/src/verifier/btc/rpc.yml @@ -26,7 +26,7 @@ types: type: uint value: descr: the block hash (same as provided) - type: long + type: uint64 tx_hash: descr: the block hash (same as provided) type: string From 977f60e449f5e17f09eb9133b926307a441b4d01 Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Sat, 30 Oct 2021 11:33:17 +0200 Subject: [PATCH 092/101] fix address --- c/src/verifier/btc/rpc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/c/src/verifier/btc/rpc.yml b/c/src/verifier/btc/rpc.yml index aa5fe9632..dbdd51f04 100644 --- a/c/src/verifier/btc/rpc.yml +++ b/c/src/verifier/btc/rpc.yml @@ -1075,7 +1075,7 @@ btc: params: from: descr: the public key derived from the private key used to sign - type: string + type: address outputs: descr: the desired outputs of the transaction type: output From 9d73f2f68193eb0956a861da08b7bfcf776c5d30 Mon Sep 17 00:00:00 2001 From: leonardotc Date: Sat, 30 Oct 2021 13:14:20 +0200 Subject: [PATCH 093/101] Add minimal rpc error treatment to btc sendtransaction --- c/src/verifier/btc/btc.c | 5 ++-- c/src/verifier/btc/btc_sign.c | 6 ++-- c/src/verifier/btc/btc_types.c | 51 +++++++++++++++++----------------- c/src/verifier/btc/btc_types.h | 12 ++++---- 4 files changed, 38 insertions(+), 36 deletions(-) diff --git a/c/src/verifier/btc/btc.c b/c/src/verifier/btc/btc.c index f05bb8e00..a329cdfc5 100644 --- a/c/src/verifier/btc/btc.c +++ b/c/src/verifier/btc/btc.c @@ -570,10 +570,11 @@ in3_ret_t send_transaction(btc_target_conf_t* conf, in3_rpc_handle_ctx_t* ctx) { bytes_t signed_tx = NULL_BYTES; btc_tx_t tx; btc_init_tx(&tx); - add_outputs_to_tx(outputs, &tx); + add_outputs_to_tx(req, outputs, &tx); btc_utxo_t* selected_utxo_list = NULL; - uint32_t utxo_list_len = btc_prepare_utxo(utxo_list, &selected_utxo_list); + uint32_t utxo_list_len = 0; + btc_prepare_utxo(utxo_list, &selected_utxo_list, &utxo_list_len); // TODO: prepare tx TRY(btc_sign_tx(ctx->req, &tx, selected_utxo_list, utxo_list_len, &pub_key)); diff --git a/c/src/verifier/btc/btc_sign.c b/c/src/verifier/btc/btc_sign.c index 8f083e807..7769267d1 100644 --- a/c/src/verifier/btc/btc_sign.c +++ b/c/src/verifier/btc/btc_sign.c @@ -62,7 +62,7 @@ in3_ret_t btc_sign_tx_in(in3_req_t* req, const btc_tx_t* tx, const btc_utxo_t* u tmp_tx_in.script.data = NULL; tmp_tx_in.script.len = 0; } - add_input_to_tx(&tmp_tx, &tmp_tx_in); + add_input_to_tx(req, &tmp_tx, &tmp_tx_in); } // prepare array for hashing @@ -131,12 +131,12 @@ in3_ret_t btc_sign_tx(in3_req_t* req, btc_tx_t* tx, const btc_utxo_t* selected_u for (uint32_t i = 0; i < utxo_list_len; i++) { // -- for each pub_key (assume we only have one pub key for now): // TODO: Allow setting a specific pub_key for each input - btc_tx_in_t tx_in; + btc_tx_in_t tx_in = {0}; prepare_tx_in(&selected_utxo_list[i], &tx_in); TRY_CATCH(btc_sign_tx_in(req, tx, selected_utxo_list, i, pub_key, &tx_in, BTC_SIGHASH_ALL), _free(tx_in.script.data); _free(tx_in.prev_tx_hash);) - add_input_to_tx(tx, &tx_in); + add_input_to_tx(req, tx, &tx_in); _free(tx_in.script.data); _free(tx_in.prev_tx_hash); } diff --git a/c/src/verifier/btc/btc_types.c b/c/src/verifier/btc/btc_types.c index e0001946b..a97a4f496 100644 --- a/c/src/verifier/btc/btc_types.c +++ b/c/src/verifier/btc/btc_types.c @@ -1,4 +1,6 @@ #include "btc_types.h" +#include "../../core/client/request.h" +#include "../../core/client/request_internal.h" #include "../../core/util/mem.h" #include "../../core/util/utils.h" #include "btc_serialize.h" @@ -53,8 +55,8 @@ uint8_t* btc_parse_tx_in(uint8_t* data, btc_tx_in_t* dst, uint8_t* limit) { // TODO: Implement support for "Coinbase" inputs // TODO: Handle null arguments // TODO: Handle max script len = 10000 bytes -void btc_serialize_tx_in(btc_tx_in_t* tx_in, bytes_t* dst) { - if (!tx_in || !dst) return; +in3_ret_t btc_serialize_tx_in(in3_req_t* req, btc_tx_in_t* tx_in, bytes_t* dst) { + if (!tx_in || !dst) return IN3_EINVAL; // calculate serialized tx input size in bytes uint32_t tx_in_size = (BTC_TX_IN_PREV_OUPUT_SIZE_BYTES + get_compact_uint_size((uint64_t) tx_in->script.len) + @@ -62,12 +64,12 @@ void btc_serialize_tx_in(btc_tx_in_t* tx_in, bytes_t* dst) { BTC_TX_IN_SEQUENCE_SIZE_BYTES); // alloc memory in dst - dst->data = malloc(tx_in_size * sizeof(*dst->data)); + dst->data = malloc(sizeof(*dst->data)); dst->len = tx_in_size; // serialize tx_in // -- Previous outpoint - if (!tx_in->prev_tx_hash) return; + if (!tx_in->prev_tx_hash) return req_set_error(req, "missing prevtash_hash", IN3_ERPC); uint32_t index = 0; for (uint32_t i = 0; i < 32; i++) { dst->data[index++] = tx_in->prev_tx_hash[31 - i]; @@ -85,6 +87,7 @@ void btc_serialize_tx_in(btc_tx_in_t* tx_in, bytes_t* dst) { // -- sequence uint_to_le(dst, index, tx_in->sequence); + return IN3_OK; } uint8_t* btc_parse_tx_out(uint8_t* data, btc_tx_out_t* dst) { @@ -120,9 +123,7 @@ void btc_serialize_tx_out(btc_tx_out_t* tx_out, bytes_t* dst) { index += get_compact_uint_size((uint64_t) tx_out->script.len); // -- pk_script - for (uint32_t i = 0; i < tx_out->script.len; i++) { - dst->data[index++] = tx_out->script.data[i]; - } + memcpy(dst->data + index, tx_out->script.data, tx_out->script.len); } in3_ret_t btc_parse_tx(bytes_t tx, btc_tx_t* dst) { @@ -177,7 +178,7 @@ in3_ret_t btc_serialize_tx(btc_tx_t* tx, bytes_t* dst) { (tx->flag ? tx->witnesses.len : 0) + BTC_TX_LOCKTIME_SIZE_BYTES); - dst->data = malloc(tx_size * sizeof(*dst->data)); + dst->data = malloc(sizeof(*dst->data)); dst->len = tx_size; // Serialize transaction data @@ -312,10 +313,9 @@ in3_ret_t btc_tx_id(btc_tx_t* tx, bytes32_t dst) { // _free(serialized_outputs); // } -void add_to_tx(btc_tx_t* tx, void* src, btc_tx_field_t field_type) { +in3_ret_t add_to_tx(in3_req_t* req, btc_tx_t* tx, void* src, btc_tx_field_t field_type) { if (!tx || !src) { - printf("ERROR: in add_to_tx: Function arguments cannot be null!\n"); - return; + return req_set_error(req, "ERROR: in add_to_tx: Function arguments cannot be null!", IN3_EINVAL); } bytes_t raw_src, *dst; @@ -323,7 +323,7 @@ void add_to_tx(btc_tx_t* tx, void* src, btc_tx_field_t field_type) { switch (field_type) { case BTC_INPUT: - btc_serialize_tx_in((btc_tx_in_t*) src, &raw_src); + btc_serialize_tx_in(req, (btc_tx_in_t*) src, &raw_src); old_len = tx->input.len; dst = &tx->input; tx->input_count++; @@ -336,7 +336,7 @@ void add_to_tx(btc_tx_t* tx, void* src, btc_tx_field_t field_type) { break; default: // TODO: Implement better error handling - printf("Unrecognized transaction field code. No action was performed."); + return req_set_error(req, "Unrecognized transaction field code. No action was performed", IN3_EINVAL); } dst->len += raw_src.len; @@ -347,18 +347,18 @@ void add_to_tx(btc_tx_t* tx, void* src, btc_tx_field_t field_type) { for (uint32_t i = 0; i < raw_src.len; i++) { dst->data[old_len + i] = raw_src.data[i]; } - return; + return IN3_OK; } -void add_input_to_tx(btc_tx_t* tx, btc_tx_in_t* tx_in) { - add_to_tx(tx, tx_in, BTC_INPUT); +in3_ret_t add_input_to_tx(in3_req_t* req, btc_tx_t* tx, btc_tx_in_t* tx_in) { + return add_to_tx(req, tx, tx_in, BTC_INPUT); } -void add_output_to_tx(btc_tx_t* tx, btc_tx_out_t* tx_out) { - add_to_tx(tx, tx_out, BTC_OUTPUT); +in3_ret_t add_output_to_tx(in3_req_t* req, btc_tx_t* tx, btc_tx_out_t* tx_out) { + return add_to_tx(req, tx, tx_out, BTC_OUTPUT); } -void add_outputs_to_tx(d_token_t* outputs, btc_tx_t* tx) { +in3_ret_t add_outputs_to_tx(in3_req_t* req, d_token_t* outputs, btc_tx_t* tx) { uint32_t len = d_len(outputs); for (uint32_t i = 0; i < len; i++) { d_token_t* output = d_get_at(outputs, i); @@ -374,16 +374,17 @@ void add_outputs_to_tx(d_token_t* outputs, btc_tx_t* tx) { tx_out.script = script; tx_out.value = value; - add_output_to_tx(tx, &tx_out); + TRY_CATCH(add_output_to_tx(req, tx, &tx_out), _free(script.data);) } + return IN3_OK; } // utxos must be freed -uint32_t btc_prepare_utxo(d_token_t* utxo_inputs, btc_utxo_t** utxos) { - uint32_t len = d_len(utxo_inputs); - *utxos = _malloc(len * sizeof(btc_utxo_t)); +in3_ret_t btc_prepare_utxo(d_token_t* utxo_inputs, btc_utxo_t** utxos, uint32_t* len) { + *len = d_len(utxo_inputs); + *utxos = _malloc(*len * sizeof(btc_utxo_t)); - for (uint32_t i = 0; i < len; i++) { + for (uint32_t i = 0; i < *len; i++) { btc_utxo_t utxo; d_token_t* utxo_input = d_get_at(utxo_inputs, i); uint32_t tx_index = d_get_long(d_get(utxo_input, key("tx_index")), 0L); @@ -407,5 +408,5 @@ uint32_t btc_prepare_utxo(d_token_t* utxo_inputs, btc_utxo_t** utxos) { *utxos[i] = utxo; } - return len; + return IN3_OK; } diff --git a/c/src/verifier/btc/btc_types.h b/c/src/verifier/btc/btc_types.h index b05e436a7..90aea0fe0 100644 --- a/c/src/verifier/btc/btc_types.h +++ b/c/src/verifier/btc/btc_types.h @@ -1,6 +1,7 @@ #ifndef _BTC_TYPES_H #define _BTC_TYPES_H +#include "../../core/client/request.h" #include "../../core/util/bytes.h" #include "../../core/util/data.h" #include "../../core/util/error.h" @@ -44,8 +45,8 @@ in3_ret_t btc_parse_tx(bytes_t tx, btc_tx_t* dst); in3_ret_t btc_serialize_tx(btc_tx_t* tx, bytes_t* dst); in3_ret_t btc_tx_id(btc_tx_t* tx, bytes32_t dst); -uint8_t* btc_parse_tx_in(uint8_t* data, btc_tx_in_t* dst, uint8_t* limit); -void btc_serialize_tx_in(btc_tx_in_t* tx_in, bytes_t* dst); +uint8_t* btc_parse_tx_in(uint8_t* data, btc_tx_in_t* dst, uint8_t* limit); +in3_ret_t btc_prepare_utxo(d_token_t* utxo_inputs, btc_utxo_t** utxos, uint32_t* len); uint8_t* btc_parse_tx_out(uint8_t* data, btc_tx_out_t* dst); void btc_serialize_tx_out(btc_tx_out_t* tx_out, bytes_t* dst); @@ -53,15 +54,14 @@ void btc_serialize_tx_out(btc_tx_out_t* tx_out, bytes_t* dst); uint32_t btc_vsize(btc_tx_t* tx); uint32_t btc_weight(btc_tx_t* tx); -void add_input_to_tx(btc_tx_t* tx, btc_tx_in_t* tx_in); -void add_output_to_tx(btc_tx_t* tx, btc_tx_out_t* tx_out); +in3_ret_t add_input_to_tx(in3_req_t* req, btc_tx_t* tx, btc_tx_in_t* tx_in); +in3_ret_t add_output_to_tx(in3_req_t* req, btc_tx_t* tx, btc_tx_out_t* tx_out); static inline bool btc_is_witness(bytes_t tx) { return tx.data[4] == 0 && tx.data[5] == 1; } -void add_outputs_to_tx(d_token_t* outputs, btc_tx_t* tx); -uint32_t btc_prepare_utxo(d_token_t* utxo_inputs, btc_utxo_t** utxos); +in3_ret_t add_outputs_to_tx(in3_req_t* req, d_token_t* outputs, btc_tx_t* tx); // void create_raw_tx(btc_tx_in_t* tx_in, uint32_t tx_in_len, btc_tx_out_t* tx_out, uint32_t tx_out_len, uint32_t lock_time, bytes_t* dst_raw_tx); From 98198043ba409175227e084414cf86f034d669cf Mon Sep 17 00:00:00 2001 From: leonardotc Date: Tue, 2 Nov 2021 14:12:35 +0100 Subject: [PATCH 094/101] Fix python transport --- python/in3/model.py | 2 ++ python/in3/transport.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/python/in3/model.py b/python/in3/model.py index 769f14bdc..a5f06bace 100644 --- a/python/in3/model.py +++ b/python/in3/model.py @@ -95,6 +95,7 @@ def __init__(self, node_signatures: int = None, node_signature_consensus: int = None, node_min_deposit: int = None, + debug: bool = None, node_list_auto_update: bool = None, node_limit: int = None, request_timeout: int = None, @@ -121,6 +122,7 @@ def __init__(self, self.bootWeights: bool = boot_weights self.includeCode: bool = response_includes_code self.keepIn3: bool = response_keep_proof + self.debug: bool = debug self.useBinary: bool = transport_binary_format self.useHttp: bool = transport_ignore_tls self.experimental: bool = experimental diff --git a/python/in3/transport.py b/python/in3/transport.py index 03348a831..1be07e195 100644 --- a/python/in3/transport.py +++ b/python/in3/transport.py @@ -26,7 +26,7 @@ def https_transport(in3_request: In3Request, in3_response: In3Response): # also the in3_request contains the http-header, which need to get added request_params = { 'url': str(in3_request.url_at(i), 'utf8'), - 'method': in3_request.method(), + 'method': str(in3_request.method(), 'utf8'), 'data': in3_request.payload(), 'headers': {'Content-type': 'application/json', 'Accept': 'application/json'}, } From 4ca6354a9dc11c224db041af62d18eeac9c36cc2 Mon Sep 17 00:00:00 2001 From: jbentke Date: Fri, 5 Nov 2021 17:44:25 +0100 Subject: [PATCH 095/101] implemented browser signer --- wasm/src/in3_util.js | 139 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) diff --git a/wasm/src/in3_util.js b/wasm/src/in3_util.js index 673bdb184..1fc5f7b95 100644 --- a/wasm/src/in3_util.js +++ b/wasm/src/in3_util.js @@ -639,3 +639,142 @@ class SimpleSigner { } IN3.SimpleSigner = SimpleSigner + +class BrowserSigner { + + constructor(getPassword) { + var self = this + if (typeof getPassword !== 'function') + throw new Error("Error: Password provider must be a function") + self.getPassword = getPassword + self.accounts = {} + self.db = {} + //create database connection + var request = indexedDB.open("in3_browser_signer"); + //create database if non existent + request.onupgradeneeded = function () { + self.db = request.result; + var store = self.db.createObjectStore("keys", { keyPath: "pubKey" }); + } + //load database if existent + request.onsuccess = function () { + self.db = request.result; + } + } + //source: https://javascript.hotexamples.com/examples/crypto-js/-/PBKDF2/javascript-pbkdf2-function-examples.html + encrypt(data, pw, iterations = 4500) { + const keySize = 256; + const salt = CryptoJS.lib.WordArray.random(128 / 8); + const key = CryptoJS.PBKDF2(pw, salt, { + iterations, + keySize: keySize / 4 + }); + const iv = CryptoJS.lib.WordArray.random(128 / 8); + const encrypted = CryptoJS.AES.encrypt(data, key, { + iv, + mode: CryptoJS.mode.CBC, + padding: CryptoJS.pad.Pkcs7 + }); + return salt.toString() + iv.toString() + encrypted.toString(); + } + //source: https://javascript.hotexamples.com/examples/crypto-js/-/PBKDF2/javascript-pbkdf2-function-examples.html + decrypt(data, pw, iterations = 4500) { + const keySize = 256; + const salt = CryptoJS.enc.Hex.parse(data.substr(0, 32)); + const iv = CryptoJS.enc.Hex.parse(data.substr(32, 32)); + const encrypted = data.substring(64); + const key = CryptoJS.PBKDF2(pw, salt, { + iterations, + keySize: keySize / 4 + }); + const decrypted = CryptoJS.AES.decrypt(encrypted, key, { + iv, + padding: CryptoJS.pad.Pkcs7, + mode: CryptoJS.mode.CBC + }); + return decrypted; + } + + //generates a private key (if non is passed) and encrypt it with user password. stores pubKey and encryptedPk + generateAndStorePrivateKey(pk = undefined) { + if (pk == undefined) + pk = IN3.util.randomBytes(32) + var pubKey = private2address(toHex(pk)) + var pw = this.getPassword() + if (pw === undefined) throw new Error("Error: Wrong password during key generation") + var encryptedPk = this.encrypt(toHex(pk), pw) + var tx = this.db.transaction("keys", "readwrite"); + var store = tx.objectStore("keys"); + store.put({ + pubKey: pubKey, + encryptedPk: encryptedPk + }) + return pubKey + } + + //returns all public keys in database + async getAccounts() { + var tx = this.db.transaction("keys", "readonly") + var store = tx.objectStore("keys"); + return new Promise((resolve) => { + //its only this complicated because of IE and some Firefox versions + //source: https://googlechrome.github.io/samples/idb-getall/ + if ('getAllKeys' in store) { + // IDBObjectStore.getAll() will return the full set of items in our store. + store.getAllKeys().onsuccess = function (event) { + resolve(event.target.result); + }; + } else { + // Fallback to the traditional cursor approach if getAll isn't supported. + var accounts = []; + store.openCursor().onsuccess = function (event) { + var cursor = event.target.result; + if (cursor) { + accounts.push(cursor.value); + cursor.continue(); + } else { + resolve(accounts); + } + }; + } + }) + + } + + async canSign(address) { + var tx = this.db.transaction("keys", "readonly"); + var store = tx.objectStore("keys"); + var storeRequest = store.get(address); + return new Promise((resolve) => { + storeRequest.onsuccess = function () { + resolve(storeRequest.result !== undefined) + } + storeRequest.onerror = function () { + throw new Error("could not find key in database") + } + }) + } + + async sign(data, account, sign_type, payloadType, meta) { + var self = this + var tx = this.db.transaction("keys", "readonly"); + var store = tx.objectStore("keys"); + var storeRequest = store.get(toChecksumAddress(account)); + var pw = this.getPassword() + if (pw === undefined) throw new Error("Error: Wrong password during signing process") + return new Promise((resolve) => { + storeRequest.onsuccess = function () { + if (storeRequest.result !== undefined) { + let pk = self.decrypt(storeRequest.result.encryptedPk, pw).toString(CryptoJS.enc.Utf8) + if (pk.length != 66) throw new Error('Error decrypting: Private Key not valid for ' + account) + resolve(ecSign(pk, data, sign_type || 'hash')) + } + else + throw new Error('Account not found for signing ' + account) + } + }) + } + +} + +IN3.BrowserSigner = BrowserSigner From f523745d9a47ad92f3df825a01cc1e548b07fe48 Mon Sep 17 00:00:00 2001 From: jbentke Date: Fri, 5 Nov 2021 17:44:43 +0100 Subject: [PATCH 096/101] changed example html for testing --- wasm/examples/in3_in_browser.html | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/wasm/examples/in3_in_browser.html b/wasm/examples/in3_in_browser.html index 4cd053f30..41b3ac62b 100644 --- a/wasm/examples/in3_in_browser.html +++ b/wasm/examples/in3_in_browser.html @@ -2,7 +2,10 @@ - + + @@ -13,10 +16,8 @@ - + \ No newline at end of file From badda7a0580838d2c9394c0c33ce38a98857a11e Mon Sep 17 00:00:00 2001 From: jbentke Date: Fri, 5 Nov 2021 19:46:56 +0100 Subject: [PATCH 097/101] changed from CryptoJs to crypto --- wasm/src/in3_util.js | 102 +++++++++++++++++++++++++++---------------- 1 file changed, 65 insertions(+), 37 deletions(-) diff --git a/wasm/src/in3_util.js b/wasm/src/in3_util.js index 1fc5f7b95..512529e75 100644 --- a/wasm/src/in3_util.js +++ b/wasm/src/in3_util.js @@ -661,48 +661,77 @@ class BrowserSigner { self.db = request.result; } } - //source: https://javascript.hotexamples.com/examples/crypto-js/-/PBKDF2/javascript-pbkdf2-function-examples.html - encrypt(data, pw, iterations = 4500) { - const keySize = 256; - const salt = CryptoJS.lib.WordArray.random(128 / 8); - const key = CryptoJS.PBKDF2(pw, salt, { - iterations, - keySize: keySize / 4 - }); - const iv = CryptoJS.lib.WordArray.random(128 / 8); - const encrypted = CryptoJS.AES.encrypt(data, key, { - iv, - mode: CryptoJS.mode.CBC, - padding: CryptoJS.pad.Pkcs7 - }); - return salt.toString() + iv.toString() + encrypted.toString(); - } - //source: https://javascript.hotexamples.com/examples/crypto-js/-/PBKDF2/javascript-pbkdf2-function-examples.html - decrypt(data, pw, iterations = 4500) { - const keySize = 256; - const salt = CryptoJS.enc.Hex.parse(data.substr(0, 32)); - const iv = CryptoJS.enc.Hex.parse(data.substr(32, 32)); - const encrypted = data.substring(64); - const key = CryptoJS.PBKDF2(pw, salt, { - iterations, - keySize: keySize / 4 - }); - const decrypted = CryptoJS.AES.decrypt(encrypted, key, { - iv, - padding: CryptoJS.pad.Pkcs7, - mode: CryptoJS.mode.CBC - }); - return decrypted; + + generateKey(pw) { + let encoder = new TextEncoder(); + return crypto.subtle.importKey( + "raw", + encoder.encode(pw), + { name: "PBKDF2" }, + false, + ["deriveBits", "deriveKey"] + ); + } + + + generateKeyFromPassword(encodedPassword, salt, iterations = 4500) { + return crypto.subtle.deriveKey( + { + name: "PBKDF2", + salt: salt, + iterations: iterations, + hash: "SHA-256" + }, + encodedPassword, + { name: "AES-GCM", length: 256 }, + true, + ["encrypt", "decrypt"] + ); + } + + async encrypt(data, pw) { + let encoder = new TextEncoder(); + const salt = crypto.getRandomValues(new Uint8Array(16)); + const iv = crypto.getRandomValues(new Uint8Array(16)); + let pp = await this.generateKey(pw) + let key = await this.generateKeyFromPassword(pp, salt); + + let encrypted = await crypto.subtle.encrypt( + { name: "AES-GCM", iv: iv }, + key, + encoder.encode(data) + ) + + return { salt: salt, iv: iv, encrypted: encrypted }; + } + + async decrypt(data, pw) { + let decoder = new TextDecoder(); + const salt = data.salt; + const iv = data.iv; + const encrypted = data.encrypted; + let pp = await this.generateKey(pw); + let key = await this.generateKeyFromPassword(pp, salt); + + const decrypted = await crypto.subtle.decrypt( + { name: "AES-GCM", iv: iv }, + key, + encrypted + ); + + return decoder.decode(decrypted); } //generates a private key (if non is passed) and encrypt it with user password. stores pubKey and encryptedPk - generateAndStorePrivateKey(pk = undefined) { + async generateAndStorePrivateKey(pk = undefined) { if (pk == undefined) pk = IN3.util.randomBytes(32) var pubKey = private2address(toHex(pk)) var pw = this.getPassword() if (pw === undefined) throw new Error("Error: Wrong password during key generation") - var encryptedPk = this.encrypt(toHex(pk), pw) + + var encryptedPk = await this.encrypt(toHex(pk), pw) + console.log(encryptedPk) var tx = this.db.transaction("keys", "readwrite"); var store = tx.objectStore("keys"); store.put({ @@ -763,9 +792,9 @@ class BrowserSigner { var pw = this.getPassword() if (pw === undefined) throw new Error("Error: Wrong password during signing process") return new Promise((resolve) => { - storeRequest.onsuccess = function () { + storeRequest.onsuccess = async function () { if (storeRequest.result !== undefined) { - let pk = self.decrypt(storeRequest.result.encryptedPk, pw).toString(CryptoJS.enc.Utf8) + let pk = await self.decrypt(storeRequest.result.encryptedPk, pw) if (pk.length != 66) throw new Error('Error decrypting: Private Key not valid for ' + account) resolve(ecSign(pk, data, sign_type || 'hash')) } @@ -774,7 +803,6 @@ class BrowserSigner { } }) } - } IN3.BrowserSigner = BrowserSigner From d6161bcee8102281a0f36a303c602dd60ffe0d83 Mon Sep 17 00:00:00 2001 From: leonardotc Date: Fri, 5 Nov 2021 22:20:52 +0100 Subject: [PATCH 098/101] fix signer --- wasm/examples/in3_in_browser.html | 11 ++++---- wasm/src/in3_util.js | 47 +++++++++++++++++++------------ 2 files changed, 34 insertions(+), 24 deletions(-) diff --git a/wasm/examples/in3_in_browser.html b/wasm/examples/in3_in_browser.html index 41b3ac62b..4cd053f30 100644 --- a/wasm/examples/in3_in_browser.html +++ b/wasm/examples/in3_in_browser.html @@ -2,10 +2,7 @@ - - + @@ -16,8 +13,10 @@ - \ No newline at end of file + diff --git a/wasm/src/in3_util.js b/wasm/src/in3_util.js index 512529e75..2fa2393c6 100644 --- a/wasm/src/in3_util.js +++ b/wasm/src/in3_util.js @@ -648,18 +648,26 @@ class BrowserSigner { throw new Error("Error: Password provider must be a function") self.getPassword = getPassword self.accounts = {} - self.db = {} - //create database connection - var request = indexedDB.open("in3_browser_signer"); - //create database if non existent - request.onupgradeneeded = function () { - self.db = request.result; - var store = self.db.createObjectStore("keys", { keyPath: "pubKey" }); - } - //load database if existent - request.onsuccess = function () { - self.db = request.result; - } + self.db = new Promise((resolve, reject) => { + //create database connection + var request = indexedDB.open("in3_browser_signer"); + //create database if non existent + request.onupgradeneeded = function () { + let db = request.result; + db.createObjectStore("keys", { keyPath: "pubKey" }); + resolve(db) + } + + //load database if existent + request.onsuccess = function () { + let db = request.result; + resolve(db) + } + + request.onerror = function (ev) { + reject(new Error("Could not access the indexdb")) + } + }) } generateKey(pw) { @@ -724,15 +732,15 @@ class BrowserSigner { //generates a private key (if non is passed) and encrypt it with user password. stores pubKey and encryptedPk async generateAndStorePrivateKey(pk = undefined) { - if (pk == undefined) - pk = IN3.util.randomBytes(32) + let db = await this.db + if (pk == undefined) pk = crypto.getRandomValues(new Uint8Array(32)) var pubKey = private2address(toHex(pk)) var pw = this.getPassword() if (pw === undefined) throw new Error("Error: Wrong password during key generation") var encryptedPk = await this.encrypt(toHex(pk), pw) console.log(encryptedPk) - var tx = this.db.transaction("keys", "readwrite"); + var tx = db.transaction("keys", "readwrite"); var store = tx.objectStore("keys"); store.put({ pubKey: pubKey, @@ -743,7 +751,8 @@ class BrowserSigner { //returns all public keys in database async getAccounts() { - var tx = this.db.transaction("keys", "readonly") + let db = await this.db + var tx = db.transaction("keys", "readonly") var store = tx.objectStore("keys"); return new Promise((resolve) => { //its only this complicated because of IE and some Firefox versions @@ -771,7 +780,8 @@ class BrowserSigner { } async canSign(address) { - var tx = this.db.transaction("keys", "readonly"); + let db = await this.db + var tx = db.transaction("keys", "readonly"); var store = tx.objectStore("keys"); var storeRequest = store.get(address); return new Promise((resolve) => { @@ -786,7 +796,8 @@ class BrowserSigner { async sign(data, account, sign_type, payloadType, meta) { var self = this - var tx = this.db.transaction("keys", "readonly"); + let db = await self.db + var tx = db.transaction("keys", "readonly"); var store = tx.objectStore("keys"); var storeRequest = store.get(toChecksumAddress(account)); var pw = this.getPassword() From 0ee6c21b14744d6aa1981cf2ff222280b9e8eb47 Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Fri, 5 Nov 2021 22:56:40 +0100 Subject: [PATCH 099/101] added typescript definition for BrowserSigner --- wasm/src/index.d.ts | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/wasm/src/index.d.ts b/wasm/src/index.d.ts index 384e7a690..94406781d 100644 --- a/wasm/src/index.d.ts +++ b/wasm/src/index.d.ts @@ -720,6 +720,30 @@ export declare class SimpleSigner implements Signer Promise } + +/** + * Signer, which stores the key encrypted in the indexDB in the browser. + */ +export declare class BrowserSigner implements Signer { + + /** creates a BrowserSigner, which will use the given callback-function in order to retrieve the password, which is used to encrypt the stored keys.*/ + constructor(passwordCB: () => String); + + /** returns all addresses managed by the signer. */ + getAccounts(): Address[] + /** adds a private key to the signer and returns the address associated with it. */ + generateAndStorePrivateKey(pk?: BufferType): Promise; + + /** returns true if the account is supported (or unlocked) */ + canSign(address: Address): Promise + + /** + * signing of any data. + * if hashFirst is true the data should be hashed first, otherwise the data is the hash. + */ + sign: (data: Hex, account: Address, sign_type: SignType, payloadType: SignPayload, meta?: any) => Promise +} + /** * Collection of different util-functions. */ From 8d088124ce063c0490c04a7f2b81273fa7c9e746 Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Sat, 6 Nov 2021 00:15:42 +0100 Subject: [PATCH 100/101] allow mac runner to fail --- c/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/c/ci.yml b/c/ci.yml index eabc285d2..05cdf2a78 100644 --- a/c/ci.yml +++ b/c/ci.yml @@ -251,6 +251,7 @@ examples_arm: examples_macos: stage: test + allow_failure: true needs: - wasm - mac_os From b0b4f7b972f8215c97d11d3b688f2e9b48b43db1 Mon Sep 17 00:00:00 2001 From: Simon Jentzsch Date: Sat, 6 Nov 2021 00:21:46 +0100 Subject: [PATCH 101/101] update autocomplet defs --- scripts/_in3.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/_in3.sh b/scripts/_in3.sh index 6b983ea71..fb4781584 100755 --- a/scripts/_in3.sh +++ b/scripts/_in3.sh @@ -32,6 +32,8 @@ subcmds=( 'getblockheader: Returns data of block header for given block hash ' 'getdifficulty: Returns the proof-of-work difficulty as a multiple of the minimum difficulty' 'getrawtransaction: Returns the raw transaction data ' + 'sendrawtransaction: sends a transaction to a btc node ' + 'sendtransaction: sends a transaction to a btc node ' 'in3_config: changes the configuration of a client ' 'eth_blockNumber: returns the number of the most recent block' 'eth_call: calls a function of a contract (or simply executes the evm opcodes) and returns the result '