diff options
-rw-r--r-- | TestHelperCrypto.h | 18 | ||||
-rw-r--r-- | crypto.cpp | 332 | ||||
-rw-r--r-- | vmIOandFlowOperationsTestFiller.json | 28 | ||||
-rw-r--r-- | vmPushDupSwapTestFiller.json | 28 | ||||
-rw-r--r-- | vmSystemOperationsTestFiller.json | 157 |
5 files changed, 449 insertions, 114 deletions
diff --git a/TestHelperCrypto.h b/TestHelperCrypto.h index cdc22ec3..01e97c21 100644 --- a/TestHelperCrypto.h +++ b/TestHelperCrypto.h @@ -21,23 +21,7 @@ #pragma once -//#include <ostream> - -#pragma warning(push) -#pragma warning(disable:4100 4244) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Wunused-parameter" -#pragma GCC diagnostic ignored "-Wunused-variable" -#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor" -#pragma GCC diagnostic ignored "-Wextra" -#include <eccrypto.h> -#include <ecp.h> -#include <files.h> -#include <osrng.h> -#include <oids.h> -#pragma warning(pop) -#pragma GCC diagnostic pop +#include <libdevcrypto/CryptoPP.h> using namespace std; using namespace CryptoPP; @@ -27,37 +27,163 @@ #include <libdevcore/Log.h> #include <libethereum/Transaction.h> #include <boost/test/unit_test.hpp> +#include <libdevcrypto/EC.h> #include "TestHelperCrypto.h" using namespace std; using namespace dev; +using namespace dev::crypto; +using namespace CryptoPP; -namespace dev -{ -namespace crypto +BOOST_AUTO_TEST_SUITE(devcrypto) + +BOOST_AUTO_TEST_CASE(common_encrypt_decrypt) { + string message("Now is the time for all good persons to come to the aide of humanity."); + bytes m = asBytes(message); + bytesConstRef bcr(&m); + + KeyPair k = KeyPair::create(); + bytes cipher; + encrypt(k.pub(), bcr, cipher); + assert(cipher != asBytes(message) && cipher.size() > 0); + + bytes plain; + decrypt(k.sec(), bytesConstRef(&cipher), plain); + + assert(asString(plain) == message); + assert(plain == asBytes(message)); +} -inline CryptoPP::AutoSeededRandomPool& PRNG() { - static CryptoPP::AutoSeededRandomPool prng; - return prng; +BOOST_AUTO_TEST_CASE(cryptopp_vs_secp256k1) +{ + ECIES<ECP>::Decryptor d(pp::PRNG(), pp::secp256k1()); + ECIES<ECP>::Encryptor e(d.GetKey()); + + Secret s; + pp::SecretFromDL_PrivateKey_EC(d.GetKey(), s); + + Public p; + pp::PublicFromDL_PublicKey_EC(e.GetKey(), p); + + assert(dev::toAddress(s) == right160(dev::sha3(p.ref()))); + + Secret previous = s; + for (auto i = 0; i < 30; i++) + { + ECIES<ECP>::Decryptor d(pp::PRNG(), pp::secp256k1()); + ECIES<ECP>::Encryptor e(d.GetKey()); + + Secret s; + pp::SecretFromDL_PrivateKey_EC(d.GetKey(), s); + assert(s != previous); + + Public p; + pp::PublicFromDL_PublicKey_EC(e.GetKey(), p); + + assert(dev::toAddress(s) == right160(dev::sha3(p.ref()))); + } } + +BOOST_AUTO_TEST_CASE(cryptopp_keys_cryptor_sipaseckp256k1) +{ + KeyPair k = KeyPair::create(); + Secret s = k.sec(); + + // Convert secret to exponent used by pp + Integer e = pp::ExponentFromSecret(s); + + // Test that exported DL_EC private is same as exponent from Secret + CryptoPP::DL_PrivateKey_EC<CryptoPP::ECP> privatek; + privatek.AccessGroupParameters().Initialize(pp::secp256k1()); + privatek.SetPrivateExponent(e); + assert(e == privatek.GetPrivateExponent()); + // Test that exported secret is same as decryptor(privatek) secret + ECIES<ECP>::Decryptor d; + d.AccessKey().AccessGroupParameters().Initialize(pp::secp256k1()); + d.AccessKey().SetPrivateExponent(e); + assert(d.AccessKey().GetPrivateExponent() == e); + + // Test that decryptor->encryptor->public == private->makepublic->public + CryptoPP::DL_PublicKey_EC<CryptoPP::ECP> pubk; + pubk.AccessGroupParameters().Initialize(pp::secp256k1()); + privatek.MakePublicKey(pubk); + + ECIES<ECP>::Encryptor enc(d); + assert(pubk.GetPublicElement() == enc.AccessKey().GetPublicElement()); + + // Test against sipa/seckp256k1 + Public p; + pp::PublicFromExponent(pp::ExponentFromSecret(s), p); + assert(toAddress(s) == dev::right160(dev::sha3(p.ref()))); + assert(k.pub() == p); } + +BOOST_AUTO_TEST_CASE(cryptopp_public_export_import) +{ + ECIES<ECP>::Decryptor d(pp::PRNG(), pp::secp256k1()); + ECIES<ECP>::Encryptor e(d.GetKey()); + + Secret s; + pp::SecretFromDL_PrivateKey_EC(d.GetKey(), s); + Public p; + pp::PublicFromDL_PublicKey_EC(e.GetKey(), p); + Address addr = right160(dev::sha3(p.ref())); + assert(toAddress(s) == addr); + + KeyPair l(s); + assert(l.address() == addr); + + DL_PublicKey_EC<ECP> pub; + pub.Initialize(pp::secp256k1(), pp::PointFromPublic(p)); + assert(pub.GetPublicElement() == e.GetKey().GetPublicElement()); + + KeyPair k = KeyPair::create(); + Public p2; + pp::PublicFromExponent(pp::ExponentFromSecret(k.sec()), p2); + assert(k.pub() == p2); + + Address a = k.address(); + Address a2 = toAddress(k.sec()); + assert(a2 == a); } -using namespace CryptoPP; +BOOST_AUTO_TEST_CASE(ecies_eckeypair) +{ + KeyPair k = KeyPair::create(); + + string message("Now is the time for all good persons to come to the aide of humanity."); + string original = message; + + bytes b = asBytes(message); + encrypt(k.pub(), b); + assert(b != asBytes(original)); -BOOST_AUTO_TEST_SUITE(crypto) + decrypt(k.sec(), b); + assert(b == asBytes(original)); +} + +BOOST_AUTO_TEST_CASE(ecdhe_aes128_ctr_sha3mac) +{ + // New connections require new ECDH keypairs + // Every new connection requires a new EC keypair + // Every new trust requires a new EC keypair + // All connections should share seed for PRF (or PRNG) for nonces + + + + + +} BOOST_AUTO_TEST_CASE(cryptopp_ecies_message) { cnote << "Testing cryptopp_ecies_message..."; - string const message("Now is the time for all good men to come to the aide of humanity."); + string const message("Now is the time for all good persons to come to the aide of humanity."); - AutoSeededRandomPool prng; - - ECIES<ECP>::Decryptor localDecryptor(prng, ASN1::secp256r1()); + ECIES<ECP>::Decryptor localDecryptor(pp::PRNG(), pp::secp256k1()); SavePrivateKey(localDecryptor.GetPrivateKey()); ECIES<ECP>::Encryptor localEncryptor(localDecryptor); @@ -65,31 +191,31 @@ BOOST_AUTO_TEST_CASE(cryptopp_ecies_message) ECIES<ECP>::Decryptor futureDecryptor; LoadPrivateKey(futureDecryptor.AccessPrivateKey()); - futureDecryptor.GetPrivateKey().ThrowIfInvalid(prng, 3); + futureDecryptor.GetPrivateKey().ThrowIfInvalid(pp::PRNG(), 3); ECIES<ECP>::Encryptor futureEncryptor; LoadPublicKey(futureEncryptor.AccessPublicKey()); - futureEncryptor.GetPublicKey().ThrowIfInvalid(prng, 3); + futureEncryptor.GetPublicKey().ThrowIfInvalid(pp::PRNG(), 3); // encrypt/decrypt with local string cipherLocal; - StringSource ss1 (message, true, new PK_EncryptorFilter(prng, localEncryptor, new StringSink(cipherLocal) ) ); + StringSource ss1 (message, true, new PK_EncryptorFilter(pp::PRNG(), localEncryptor, new StringSink(cipherLocal) ) ); string plainLocal; - StringSource ss2 (cipherLocal, true, new PK_DecryptorFilter(prng, localDecryptor, new StringSink(plainLocal) ) ); + StringSource ss2 (cipherLocal, true, new PK_DecryptorFilter(pp::PRNG(), localDecryptor, new StringSink(plainLocal) ) ); // encrypt/decrypt with future string cipherFuture; - StringSource ss3 (message, true, new PK_EncryptorFilter(prng, futureEncryptor, new StringSink(cipherFuture) ) ); + StringSource ss3 (message, true, new PK_EncryptorFilter(pp::PRNG(), futureEncryptor, new StringSink(cipherFuture) ) ); string plainFuture; - StringSource ss4 (cipherFuture, true, new PK_DecryptorFilter(prng, futureDecryptor, new StringSink(plainFuture) ) ); + StringSource ss4 (cipherFuture, true, new PK_DecryptorFilter(pp::PRNG(), futureDecryptor, new StringSink(plainFuture) ) ); // decrypt local w/future string plainFutureFromLocal; - StringSource ss5 (cipherLocal, true, new PK_DecryptorFilter(prng, futureDecryptor, new StringSink(plainFutureFromLocal) ) ); + StringSource ss5 (cipherLocal, true, new PK_DecryptorFilter(pp::PRNG(), futureDecryptor, new StringSink(plainFutureFromLocal) ) ); // decrypt future w/local string plainLocalFromFuture; - StringSource ss6 (cipherFuture, true, new PK_DecryptorFilter(prng, localDecryptor, new StringSink(plainLocalFromFuture) ) ); + StringSource ss6 (cipherFuture, true, new PK_DecryptorFilter(pp::PRNG(), localDecryptor, new StringSink(plainLocalFromFuture) ) ); assert(plainLocal == message); @@ -98,98 +224,112 @@ BOOST_AUTO_TEST_CASE(cryptopp_ecies_message) assert(plainLocalFromFuture == plainLocal); } -BOOST_AUTO_TEST_CASE(cryptopp_ecdh_prime) +BOOST_AUTO_TEST_CASE(cryptopp_aes128_ctr) { - cnote << "Testing cryptopp_ecdh_prime..."; + const int aesKeyLen = 16; + assert(sizeof(char) == sizeof(byte)); - using namespace CryptoPP; - OID curve = ASN1::secp256r1(); - - ECDH<ECP>::Domain dhLocal(curve); - SecByteBlock privLocal(dhLocal.PrivateKeyLength()); - SecByteBlock pubLocal(dhLocal.PublicKeyLength()); - dhLocal.GenerateKeyPair(dev::crypto::PRNG(), privLocal, pubLocal); + // generate test key + AutoSeededRandomPool rng; + SecByteBlock key(0x00, aesKeyLen); + rng.GenerateBlock(key, key.size()); - ECDH<ECP>::Domain dhRemote(curve); - SecByteBlock privRemote(dhRemote.PrivateKeyLength()); - SecByteBlock pubRemote(dhRemote.PublicKeyLength()); - dhRemote.GenerateKeyPair(dev::crypto::PRNG(), privRemote, pubRemote); + // cryptopp uses IV as nonce/counter which is same as using nonce w/0 ctr + byte ctr[AES::BLOCKSIZE]; + rng.GenerateBlock(ctr, sizeof(ctr)); - assert(dhLocal.AgreedValueLength() == dhRemote.AgreedValueLength()); + string text = "Now is the time for all good persons to come to the aide of humanity."; + // c++11 ftw + unsigned char const* in = (unsigned char*)&text[0]; + unsigned char* out = (unsigned char*)&text[0]; + string original = text; - // local: send public to remote; remote: send public to local + string cipherCopy; + try + { + CTR_Mode<AES>::Encryption e; + e.SetKeyWithIV(key, key.size(), ctr); + e.ProcessData(out, in, text.size()); + assert(text != original); + cipherCopy = text; + } + catch(CryptoPP::Exception& e) + { + cerr << e.what() << endl; + } - // Local - SecByteBlock sharedLocal(dhLocal.AgreedValueLength()); - assert(dhLocal.Agree(sharedLocal, privLocal, pubRemote)); + try + { + CTR_Mode< AES >::Decryption d; + d.SetKeyWithIV(key, key.size(), ctr); + d.ProcessData(out, in, text.size()); + assert(text == original); + } + catch(CryptoPP::Exception& e) + { + cerr << e.what() << endl; + } - // Remote - SecByteBlock sharedRemote(dhRemote.AgreedValueLength()); - assert(dhRemote.Agree(sharedRemote, privRemote, pubLocal)); - // Test - Integer ssLocal, ssRemote; - ssLocal.Decode(sharedLocal.BytePtr(), sharedLocal.SizeInBytes()); - ssRemote.Decode(sharedRemote.BytePtr(), sharedRemote.SizeInBytes()); + // reencrypt ciphertext... + try + { + assert(cipherCopy != text); + in = (unsigned char*)&cipherCopy[0]; + out = (unsigned char*)&cipherCopy[0]; + + CTR_Mode<AES>::Encryption e; + e.SetKeyWithIV(key, key.size(), ctr); + e.ProcessData(out, in, text.size()); + + // yep, ctr mode. + assert(cipherCopy == original); + } + catch(CryptoPP::Exception& e) + { + cerr << e.what() << endl; + } - assert(ssLocal != 0); - assert(ssLocal == ssRemote); } -BOOST_AUTO_TEST_CASE(cryptopp_ecdh_aes128_cbc_noauth) +BOOST_AUTO_TEST_CASE(cryptopp_aes128_cbc) { - // ECDH gives 256-bit shared while aes uses 128-bits - // Use first 128-bits of shared secret as symmetric key - // IV is 0 - // New connections require new ECDH keypairs + const int aesKeyLen = 16; + assert(sizeof(char) == sizeof(byte)); + AutoSeededRandomPool rng; + SecByteBlock key(0x00, aesKeyLen); + rng.GenerateBlock(key, key.size()); -} + // Generate random IV + byte iv[AES::BLOCKSIZE]; + rng.GenerateBlock(iv, AES::BLOCKSIZE); -BOOST_AUTO_TEST_CASE(cryptopp_eth_fbba) -{ - // Initial Authentication: - // - // New/Known Peer: - // pubkeyL = knownR? ? myKnown : myECDH - // pubkeyR = knownR? ? theirKnown : theirECDH - // - // Initial message = hmac(k=sha3(shared-secret[128..255]), address(pubkeyL)) || ECIES encrypt(pubkeyR, pubkeyL) - // - // Key Exchange (this could occur after handshake messages): - // If peers do not know each other they will need to exchange public keys. - // - // Drop ECDH (this could occur after handshake messages): - // After authentication and/or key exchange, both sides generate shared key - // from their 'known' keys and use this to encrypt all future messages. - // - // v2: If one side doesn't trust the other then a single-use key maybe sent. - // This will need to be tracked for future connections; when non-trusting peer - // wants to trust the other, it can request that it's old, 'new', public key be - // accepted. And, if the peer *really* doesn't trust the other side, it can request - // that a new, 'new', public key be accepted. - // - // Handshake (all or nothing, padded): - // All Peers (except blacklisted): - // - // - // New Peer: - // - // - // Known Untrusted Peer: - // - // - // Known Trusted Peer: - // - // - // Blacklisted Peeer: - // Already dropped by now. - // - // - // MAC: - // ... -} + string string128("AAAAAAAAAAAAAAAA"); + string plainOriginal = string128; + CryptoPP::CBC_Mode<Rijndael>::Encryption cbcEncryption(key, key.size(), iv); + cbcEncryption.ProcessData((byte*)&string128[0], (byte*)&string128[0], string128.size()); + assert(string128 != plainOriginal); + + CBC_Mode<Rijndael>::Decryption cbcDecryption(key, key.size(), iv); + cbcDecryption.ProcessData((byte*)&string128[0], (byte*)&string128[0], string128.size()); + assert(plainOriginal == string128); + + + // plaintext whose size isn't divisible by block size must use stream filter for padding + string string192("AAAAAAAAAAAAAAAABBBBBBBB"); + plainOriginal = string192; + + string cipher; + StreamTransformationFilter* aesStream = new StreamTransformationFilter(cbcEncryption, new StringSink(cipher)); + StringSource source(string192, true, aesStream); + assert(cipher.size() == 32); + + cbcDecryption.ProcessData((byte*)&cipher[0], (byte*)&string192[0], cipher.size()); + assert(string192 == plainOriginal); +} + BOOST_AUTO_TEST_CASE(eth_keypairs) { cnote << "Testing Crypto..."; diff --git a/vmIOandFlowOperationsTestFiller.json b/vmIOandFlowOperationsTestFiller.json index 79d162c8..a470b9c8 100644 --- a/vmIOandFlowOperationsTestFiller.json +++ b/vmIOandFlowOperationsTestFiller.json @@ -670,6 +670,34 @@ } }, + "jumpi2": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "0x60017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff596002600357", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "10000" + } + }, + "pc0": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", diff --git a/vmPushDupSwapTestFiller.json b/vmPushDupSwapTestFiller.json index 1bb3e663..52c704d4 100644 --- a/vmPushDupSwapTestFiller.json +++ b/vmPushDupSwapTestFiller.json @@ -27,6 +27,34 @@ } }, + "push1_missingStack": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "0x60", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "10000" + } + }, + "push2": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", diff --git a/vmSystemOperationsTestFiller.json b/vmSystemOperationsTestFiller.json index c948f043..1df2697e 100644 --- a/vmSystemOperationsTestFiller.json +++ b/vmSystemOperationsTestFiller.json @@ -509,7 +509,7 @@ } }, - "CallRecursiveBomb": { + "CallRecursiveBomb0": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", @@ -543,6 +543,90 @@ } }, + "CallRecursiveBomb1": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "20000000", + "nonce" : 0, + "code" : "{ [[ 0 ]] (+ (SLOAD 0) 1) [[ 1 ]] (CALL (- (GAS) 224) (ADDRESS) 0 0 0 0 0) }", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "100000", + "data" : "", + "gasPrice" : "1", + "gas" : "364723" + } + }, + + "CallRecursiveBomb2": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "20000000", + "nonce" : 0, + "code" : "{ [[ 0 ]] (+ (SLOAD 0) 1) [[ 1 ]] (CALL (- (GAS) 224) (ADDRESS) 0 0 0 0 0) }", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "100000", + "data" : "", + "gasPrice" : "1", + "gas" : "364724" + } + }, + + "CallRecursiveBomb3": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "20000000", + "nonce" : 0, + "code" : "{ [[ 0 ]] (+ (SLOAD 0) 1) [[ 1 ]] (CALL (- (GAS) 224) (ADDRESS) 0 0 0 0 0) }", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "100000", + "data" : "", + "gasPrice" : "1", + "gas" : "1000000" + } + }, + "suicide0": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", @@ -949,6 +1033,77 @@ } }, + "ABAcalls2": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : 0, + "code" : "{ [[ 0 ]] (ADD (SLOAD 0) 1) (CALL (- (GAS) 1000) 0x945304eb96065b2a98b57a48a06ae28d285a71b5 1 0 0 0 0) }", + "storage": {} + }, + "945304eb96065b2a98b57a48a06ae28d285a71b5" : { + "balance" : "0", + "code" : " { [[ 0 ]] (ADD (SLOAD 0) 1) (CALL (- (GAS) 1000) 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 0 0 0 0 0) } ", + "nonce" : "0", + "storage" : { + } + } + + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "100000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "10000000000000" + } + }, + + "ABAcalls3": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1025000", + "nonce" : 0, + "code" : "{ [[ 0 ]] (ADD (SLOAD 0) 1) (CALL (- (GAS) 1000) 0x945304eb96065b2a98b57a48a06ae28d285a71b5 1 0 0 0 0) }", + "storage": {} + }, + "945304eb96065b2a98b57a48a06ae28d285a71b5" : { + "balance" : "0", + "code" : " { [[ 0 ]] (ADD (SLOAD 0) 1) (CALL (- (GAS) 1000) 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 0 0 0 0 0) } ", + "nonce" : "0", + "storage" : { + } + } + + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "100000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "1000000" + } + }, "ABAcallsSuicide0": { "env" : { |