From 384de1c8859947b1c47f6002a47406edd573c877 Mon Sep 17 00:00:00 2001 From: Thomas Zamojski Date: Fri, 17 Nov 2023 12:40:06 +0100 Subject: [PATCH] FIX: bug in TrieKeyAdaptor swapLastByte swapLastByte did not take properly into account the last byte of a UInt256. Also, the UInt256 is reversed to littleEndian as part of the routine. More tests have been included for contract code chunking. Signed-off-by: Thomas Zamojski --- .../trie/verkle/adapter/TrieKeyAdapter.java | 13 ++-- .../trie/verkle/TrieKeyAdapterTest.java | 73 +++++++++++++++---- ...erc20CodeChunks.json => chunkifyCode.json} | 0 src/test/resources/contractCode.json | 53 ++++++++++++++ 4 files changed, 118 insertions(+), 21 deletions(-) rename src/test/resources/{erc20CodeChunks.json => chunkifyCode.json} (100%) create mode 100644 src/test/resources/contractCode.json diff --git a/src/main/java/org/hyperledger/besu/ethereum/trie/verkle/adapter/TrieKeyAdapter.java b/src/main/java/org/hyperledger/besu/ethereum/trie/verkle/adapter/TrieKeyAdapter.java index a1d3af8..00841b4 100644 --- a/src/main/java/org/hyperledger/besu/ethereum/trie/verkle/adapter/TrieKeyAdapter.java +++ b/src/main/java/org/hyperledger/besu/ethereum/trie/verkle/adapter/TrieKeyAdapter.java @@ -59,8 +59,9 @@ public TrieKeyAdapter(Hasher hasher) { * @param subIndex The subIndex. * @return The modified key. */ - Bytes32 swapLastByte(Bytes32 base, Bytes subIndex) { - return (Bytes32) Bytes.concatenate(base.slice(0, 31), subIndex); + Bytes32 swapLastByte(Bytes32 base, UInt256 subIndex) { + Bytes lastByte = Bytes.of(subIndex.toBytes().reverse().get(0)); + return (Bytes32) Bytes.concatenate(base.slice(0, 31), lastByte); } /** @@ -77,7 +78,7 @@ public Bytes32 storageKey(Bytes address, Bytes32 storageKey) { ((index.compareTo(headerOffset) < 0) ? HEADER_STORAGE_OFFSET : MAIN_STORAGE_OFFSET); UInt256 pos = offset.add(index); Bytes32 base = hasher.trieKeyHash(address, pos.divide(VERKLE_NODE_WIDTH)); - Bytes32 key = swapLastByte(base, pos.mod(VERKLE_NODE_WIDTH).toMinimalBytes()); + Bytes32 key = swapLastByte(base, pos.mod(VERKLE_NODE_WIDTH)); return key; } @@ -88,7 +89,7 @@ public Bytes32 storageKey(Bytes address, Bytes32 storageKey) { * @param chunkId The chunk ID. * @return The generated code chunk key. */ - public Bytes32 codeChunkKey(Bytes address, long chunkId) { + public Bytes32 codeChunkKey(Bytes address, int chunkId) { return codeChunkKey(address, UInt256.valueOf(chunkId)); } @@ -102,7 +103,7 @@ public Bytes32 codeChunkKey(Bytes address, long chunkId) { public Bytes32 codeChunkKey(Bytes address, UInt256 chunkId) { UInt256 pos = CODE_OFFSET.add(chunkId); Bytes32 base = hasher.trieKeyHash(address, pos.divide(VERKLE_NODE_WIDTH).toBytes()); - Bytes32 key = swapLastByte(base, pos.mod(VERKLE_NODE_WIDTH).toMinimalBytes()); + Bytes32 key = swapLastByte(base, pos.mod(VERKLE_NODE_WIDTH)); return key; } @@ -115,7 +116,7 @@ public Bytes32 codeChunkKey(Bytes address, UInt256 chunkId) { */ Bytes32 headerKey(Bytes address, UInt256 leafKey) { Bytes32 base = hasher.trieKeyHash(address, UInt256.valueOf(0).toBytes()); - Bytes32 key = swapLastByte(base, leafKey.toBytes().slice(31)); + Bytes32 key = swapLastByte(base, leafKey); return key; } diff --git a/src/test/java/org/hyperledger/besu/ethereum/trie/verkle/TrieKeyAdapterTest.java b/src/test/java/org/hyperledger/besu/ethereum/trie/verkle/TrieKeyAdapterTest.java index 052f54b..c7af3c5 100644 --- a/src/test/java/org/hyperledger/besu/ethereum/trie/verkle/TrieKeyAdapterTest.java +++ b/src/test/java/org/hyperledger/besu/ethereum/trie/verkle/TrieKeyAdapterTest.java @@ -18,7 +18,7 @@ import static org.assertj.core.api.Assertions.assertThat; import org.hyperledger.besu.ethereum.trie.verkle.adapter.TrieKeyAdapter; -import org.hyperledger.besu.ethereum.trie.verkle.hasher.SHA256Hasher; +import org.hyperledger.besu.ethereum.trie.verkle.hasher.PedersenHasher; import java.io.IOException; import java.io.InputStream; @@ -36,14 +36,14 @@ public class TrieKeyAdapterTest { Bytes address = Bytes.fromHexString("0x00112233445566778899aabbccddeeff00112233"); - TrieKeyAdapter adapter = new TrieKeyAdapter(new SHA256Hasher()); + TrieKeyAdapter adapter = new TrieKeyAdapter(new PedersenHasher()); @Test public void testStorageKey() { UInt256 storageKey = UInt256.valueOf(32); // Need to change this once commit is fixed Bytes32 expected = - Bytes32.fromHexString("0x1719aec0fd8358bc50c95799bd3cd38da48f6519f78d64ccb2546f554d80a060"); + Bytes32.fromHexString("0xc224b9edaff18b27ce2604ad0f33a162d19840fd25290436dedcce42ad15d260"); assertThat(adapter.storageKey(address, storageKey)).isEqualTo(expected); } @@ -52,15 +52,25 @@ public void testCodeChunkKey() { UInt256 chunkId = UInt256.valueOf(24); // Need to change this once commit is fixed Bytes32 expected = - Bytes32.fromHexString("0x1719aec0fd8358bc50c95799bd3cd38da48f6519f78d64ccb2546f554d80a098"); + Bytes32.fromHexString("0xc224b9edaff18b27ce2604ad0f33a162d19840fd25290436dedcce42ad15d298"); assertThat(adapter.codeChunkKey(address, chunkId)).isEqualTo(expected); } + @Test + public void testCodeChunkKey2() { + Bytes addr = Bytes.fromHexString("0x6f22ffbc56eff051aecf839396dd1ed9ad6bba9d"); + UInt256 chunkId = + UInt256.fromHexString("0x0000000000000000000000000000000000000000000000000000000000000080"); + Bytes32 expected = + Bytes32.fromHexString("0x07361aa490296db032a91d3a5a69d3c3ef0e477baf8fced7f6775e4739614200"); + assertThat(adapter.codeChunkKey(addr, chunkId)).isEqualTo(expected); + } + @Test public void testVersionKey() { // Need to change this once commit is fixed Bytes32 expected = - Bytes32.fromHexString("0x1719aec0fd8358bc50c95799bd3cd38da48f6519f78d64ccb2546f554d80a000"); + Bytes32.fromHexString("0xc224b9edaff18b27ce2604ad0f33a162d19840fd25290436dedcce42ad15d200"); assertThat(adapter.versionKey(address)).isEqualTo(expected); } @@ -68,7 +78,7 @@ public void testVersionKey() { public void testBalanceKey() { // Need to change this once commit is fixed Bytes32 expected = - Bytes32.fromHexString("0x1719aec0fd8358bc50c95799bd3cd38da48f6519f78d64ccb2546f554d80a001"); + Bytes32.fromHexString("0xc224b9edaff18b27ce2604ad0f33a162d19840fd25290436dedcce42ad15d201"); assertThat(adapter.balanceKey(address)).isEqualTo(expected); } @@ -76,7 +86,7 @@ public void testBalanceKey() { public void testNonceKey() { // Need to change this once commit is fixed Bytes32 expected = - Bytes32.fromHexString("0x1719aec0fd8358bc50c95799bd3cd38da48f6519f78d64ccb2546f554d80a002"); + Bytes32.fromHexString("0xc224b9edaff18b27ce2604ad0f33a162d19840fd25290436dedcce42ad15d202"); assertThat(adapter.nonceKey(address)).isEqualTo(expected); } @@ -84,7 +94,7 @@ public void testNonceKey() { public void testCodeKeccakKey() { // Need to change this once commit is fixed Bytes32 expected = - Bytes32.fromHexString("0x1719aec0fd8358bc50c95799bd3cd38da48f6519f78d64ccb2546f554d80a003"); + Bytes32.fromHexString("0xc224b9edaff18b27ce2604ad0f33a162d19840fd25290436dedcce42ad15d203"); assertThat(adapter.codeKeccakKey(address)).isEqualTo(expected); } @@ -92,25 +102,25 @@ public void testCodeKeccakKey() { public void testCodeSizeKey() { // Need to change this once commit is fixed Bytes32 expected = - Bytes32.fromHexString("0x1719aec0fd8358bc50c95799bd3cd38da48f6519f78d64ccb2546f554d80a004"); + Bytes32.fromHexString("0xc224b9edaff18b27ce2604ad0f33a162d19840fd25290436dedcce42ad15d204"); assertThat(adapter.codeSizeKey(address)).isEqualTo(expected); } private static final ObjectMapper objectMapper = new ObjectMapper(); - public static List JsonData() throws IOException { - InputStream inputStream = TrieKeyAdapterTest.class.getResourceAsStream("/erc20CodeChunks.json"); - return objectMapper.readValue(inputStream, new TypeReference>() {}); + public static List JsonChunkifyData() throws IOException { + InputStream inputStream = TrieKeyAdapterTest.class.getResourceAsStream("/chunkifyCode.json"); + return objectMapper.readValue(inputStream, new TypeReference>() {}); } - static class TestData { + static class TestChunkifyData { public String bytecode; public ArrayList chunks; } @ParameterizedTest - @MethodSource("JsonData") - public void TestChunkifyCode(TestData testData) { + @MethodSource("JsonChunkifyData") + public void TestChunkifyCode(TestChunkifyData testData) { Bytes bytecode = Bytes.fromHexString(testData.bytecode); List result = adapter.chunkifyCode(bytecode); assertThat(testData.chunks.size()).isEqualTo(result.size()); @@ -123,4 +133,37 @@ public void TestChunkifyCode(TestData testData) { // expected.add(value); } } + + static class KeyValueData { + public String key; + public String value; + } + + static class TestCodeData { + public String address; + public String bytecode; + public ArrayList chunks; + } + + public static List JsonContractCodeData() throws IOException { + InputStream inputStream = TrieKeyAdapterTest.class.getResourceAsStream("/contractCode.json"); + return objectMapper.readValue(inputStream, new TypeReference>() {}); + } + + @ParameterizedTest + @MethodSource("JsonContractCodeData") + public void TestContractCode(TestCodeData testData) { + Bytes addr = Bytes.fromHexString(testData.address); + Bytes bytecode = Bytes.fromHexString(testData.bytecode); + List chunks = adapter.chunkifyCode(bytecode); + assertThat(chunks.size()).as("Same number of chunks").isEqualTo(testData.chunks.size()); + for (int i = 0; i < chunks.size(); ++i) { + Bytes32 key = adapter.codeChunkKey(addr, UInt256.valueOf(i)); + Bytes32 expectedKey = Bytes32.fromHexString(testData.chunks.get(i).key); + assertThat(key).as(String.format("Key %s", i)).isEqualTo(expectedKey); + Bytes32 value = chunks.get(i); + Bytes32 expectedValue = Bytes32.fromHexString(testData.chunks.get(i).value); + assertThat(value).as(String.format("Value %s", i)).isEqualTo(expectedValue); + } + } } diff --git a/src/test/resources/erc20CodeChunks.json b/src/test/resources/chunkifyCode.json similarity index 100% rename from src/test/resources/erc20CodeChunks.json rename to src/test/resources/chunkifyCode.json diff --git a/src/test/resources/contractCode.json b/src/test/resources/contractCode.json new file mode 100644 index 0000000..2c18edc --- /dev/null +++ b/src/test/resources/contractCode.json @@ -0,0 +1,53 @@ +[ + { + "address": "0x2a97e18168654393a573599759104efdfec6d8bd", + "bytecode": "0x608060405234801561000f575f80fd5b5060043610610034575f3560e01c80632e64cec1146100385780636057361d14610056575b5f80fd5b610040610072565b60405161004d919061029a565b60405180910390f35b610070600480360381019061006b91906102e1565b61019c565b005b5f8060405161008090610275565b604051809103905ff080158015610099573d5f803e3d5ffd5b5090505f60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632e64cec16040518163ffffffff1660e01b8152600401602060405180830381865afa158015610107573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061012b9190610320565b90508173ffffffffffffffffffffffffffffffffffffffff16636057361d826040518263ffffffff1660e01b8152600401610166919061029a565b5f604051808303815f87803b15801561017d575f80fd5b505af115801561018f573d5f803e3d5ffd5b505050505f549250505090565b805f819055505f6040516101af90610275565b604051809103905ff0801580156101c8573d5f803e3d5ffd5b5090508073ffffffffffffffffffffffffffffffffffffffff16636057361d836040518263ffffffff1660e01b8152600401610204919061029a565b5f604051808303815f87803b15801561021b575f80fd5b505af115801561022d573d5f803e3d5ffd5b505050508060015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b6101e38061034c83390190565b5f819050919050565b61029481610282565b82525050565b5f6020820190506102ad5f83018461028b565b92915050565b5f80fd5b6102c081610282565b81146102ca575f80fd5b50565b5f813590506102db816102b7565b92915050565b5f602082840312156102f6576102f56102b3565b5b5f610303848285016102cd565b91505092915050565b5f8151905061031a816102b7565b92915050565b5f60208284031215610335576103346102b3565b5b5f6103428482850161030c565b9150509291505056fe608060405234801561000f575f80fd5b506101c68061001d5f395ff3fe60806040526004361061003e575f3560e01c80632711432d146100425780632e64cec11461006c5780636057361d14610096578063d64c8ca4146100be575b5f80fd5b34801561004d575f80fd5b506100566100c8565b604051610063919061011e565b60405180910390f35b348015610077575f80fd5b506100806100d1565b60405161008d919061011e565b60405180910390f35b3480156100a1575f80fd5b506100bc60048036038101906100b79190610165565b6100d9565b005b6100c66100e9565b005b5f600154905090565b5f8054905090565b805f819055508060018190555050565b5f3390508073ffffffffffffffffffffffffffffffffffffffff16ff5b5f819050919050565b61011881610106565b82525050565b5f6020820190506101315f83018461010f565b92915050565b5f80fd5b61014481610106565b811461014e575f80fd5b50565b5f8135905061015f8161013b565b92915050565b5f6020828403121561017a57610179610137565b5b5f61018784828501610151565b9150509291505056fea2646970667358221220dc349a9524617af5742ac60346440c0d09b175e4d9c4d95e378a9652cb9acbb064736f6c63430008160033a264697066735822122079744fe4f745783dffcec2415a6b99b8b7b340bcf4a768d5563f00d2ec1f916b64736f6c63430008160033", + "chunks": [ + {"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b80", "value":"0x00608060405234801561000f575f80fd5b5060043610610034575f3560e01c80"}, + {"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b81", "value":"0x00632e64cec1146100385780636057361d14610056575b5f80fd5b6100406100"}, + {"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b82", "value":"0x0172565b60405161004d919061029a565b60405180910390f35b610070600480"}, + {"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b83", "value":"0x00360381019061006b91906102e1565b61019c565b005b5f8060405161008090"}, + {"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b84", "value":"0x00610275565b604051809103905ff080158015610099573d5f803e3d5ffd5b50"}, + {"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b85", "value":"0x0090505f60015f9054906101000a900473ffffffffffffffffffffffffffffff"}, + {"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b86", "value":"0x05ffffffffff1673ffffffffffffffffffffffffffffffffffffffff16632e64"}, + {"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b87", "value":"0x02cec16040518163ffffffff1660e01b8152600401602060405180830381865a"}, + {"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b88", "value":"0x00fa158015610107573d5f803e3d5ffd5b505050506040513d601f19601f8201"}, + {"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b89", "value":"0x00168201806040525081019061012b9190610320565b90508173ffffffffffff"}, + {"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b8a", "value":"0x0effffffffffffffffffffffffffff16636057361d826040518263ffffffff16"}, + {"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b8b", "value":"0x0060e01b8152600401610166919061029a565b5f604051808303815f87803b15"}, + {"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b8c", "value":"0x00801561017d575f80fd5b505af115801561018f573d5f803e3d5ffd5b505050"}, + {"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b8d", "value":"0x00505f549250505090565b805f819055505f6040516101af90610275565b6040"}, + {"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b8e", "value":"0x0051809103905ff0801580156101c8573d5f803e3d5ffd5b5090508073ffffff"}, + {"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b8f", "value":"0x11ffffffffffffffffffffffffffffffffff16636057361d836040518263ffff"}, + {"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b90", "value":"0x02ffff1660e01b8152600401610204919061029a565b5f604051808303815f87"}, + {"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b91", "value":"0x00803b15801561021b575f80fd5b505af115801561022d573d5f803e3d5ffd5b"}, + {"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b92", "value":"0x00505050508060015f6101000a81548173ffffffffffffffffffffffffffffff"}, + {"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b93", "value":"0x05ffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff"}, + {"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b94", "value":"0x001602179055505050565b6101e38061034c83390190565b5f81905091905056"}, + {"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b95", "value":"0x005b61029481610282565b82525050565b5f6020820190506102ad5f83018461"}, + {"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b96", "value":"0x02028b565b92915050565b5f80fd5b6102c081610282565b81146102ca575f80"}, + {"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b97", "value":"0x00fd5b50565b5f813590506102db816102b7565b92915050565b5f6020828403"}, + {"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b98", "value":"0x0012156102f6576102f56102b3565b5b5f610303848285016102cd565b915050"}, + {"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b99", "value":"0x0092915050565b5f8151905061031a816102b7565b92915050565b5f60208284"}, + {"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b9a", "value":"0x00031215610335576103346102b3565b5b5f6103428482850161030c565b9150"}, + {"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b9b", "value":"0x00509291505056fe608060405234801561000f575f80fd5b506101c68061001d"}, + {"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b9c", "value":"0x005f395ff3fe60806040526004361061003e575f3560e01c80632711432d1461"}, + {"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b9d", "value":"0x0200425780632e64cec11461006c5780636057361d14610096578063d64c8ca4"}, + {"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b9e", "value":"0x00146100be575b5f80fd5b34801561004d575f80fd5b506100566100c8565b60"}, + {"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09b9f", "value":"0x014051610063919061011e565b60405180910390f35b348015610077575f80fd"}, + {"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09ba0", "value":"0x005b506100806100d1565b60405161008d919061011e565b60405180910390f3"}, + {"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09ba1", "value":"0x005b3480156100a1575f80fd5b506100bc60048036038101906100b791906101"}, + {"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09ba2", "value":"0x0165565b6100d9565b005b6100c66100e9565b005b5f600154905090565b5f80"}, + {"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09ba3", "value":"0x0054905090565b805f819055508060018190555050565b5f3390508073ffffff"}, + {"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09ba4", "value":"0x11ffffffffffffffffffffffffffffffffff16ff5b5f819050919050565b6101"}, + {"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09ba5", "value":"0x011881610106565b82525050565b5f6020820190506101315f83018461010f56"}, + {"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09ba6", "value":"0x005b92915050565b5f80fd5b61014481610106565b811461014e575f80fd5b50"}, + {"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09ba7", "value":"0x00565b5f8135905061015f8161013b565b92915050565b5f6020828403121561"}, + {"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09ba8", "value":"0x02017a57610179610137565b5b5f61018784828501610151565b915050929150"}, + {"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09ba9", "value":"0x005056fea2646970667358221220dc349a9524617af5742ac60346440c0d09b1"}, + {"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09baa", "value":"0x0c75e4d9c4d95e378a9652cb9acbb064736f6c63430008160033a26469706673"}, + {"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09bab", "value":"0x015822122079744fe4f745783dffcec2415a6b99b8b7b340bcf4a768d5563f00"}, + {"key":"0xf0c7bf7821bc37c3074a1ea01bc6bf6d0d3f9d29c36b85be1b88a26472a09bac", "value":"0x00d2ec1f916b64736f6c63430008160033000000000000000000000000000000"} + ] + } +] \ No newline at end of file