From b5eb3b7a9deac927ffe8d08305323ae25d42dcfb Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sun, 19 Jan 2014 13:54:06 +0000 Subject: [PATCH] Cleanups and preparation. --- eth/main.cpp | 10 ++++++---- libethereum/Common.cpp | 19 ++++++++++++++++++- libethereum/Common.h | 5 +++++ libethereum/State.cpp | 16 ++++++++++++---- 4 files changed, 41 insertions(+), 9 deletions(-) diff --git a/eth/main.cpp b/eth/main.cpp index 0af33fb81..012b43670 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -29,14 +29,16 @@ using namespace eth; int main() { // Our address. - Address us; // TODO: should be loaded from config file/set at command-line. + h256 privkey = sha3("123"); + Address us = toPublic(privkey); // TODO: should be loaded from config file/set at command-line. BlockChain bc; // Maintains block database. TransactionQueue tq; // Maintains list of incoming transactions not yet on the block chain. - State s(us); // TODO: Switch to disk-backed state (leveldb? could do with a diffing DB) -// s.restore(); // TODO: Implement - key optimisation. + State s(us); - // Synchronise the state according to the block chain - i.e. replay all transactions, in order. Will take a while if the state isn't restored. + // Synchronise the state according to the block chain - i.e. replay all transactions in block chain, in order. + // In practise this won't need to be done since the State DB will contain the keys for the tries for most recent (and many old) blocks. + // TODO: currently it contains keys for *all* blocks. Make it remove old ones. s.sync(bc); s.sync(tq); diff --git a/libethereum/Common.cpp b/libethereum/Common.cpp index 86de1e7eb..642a1ab48 100644 --- a/libethereum/Common.cpp +++ b/libethereum/Common.cpp @@ -24,11 +24,11 @@ #else #pragma GCC diagnostic ignored "-Wunused-function" #endif +#include #include #if WIN32 #pragma warning(pop) #else -#pragma GCC diagnostic warning "-Wunused-function" #endif #include #include "Common.h" @@ -143,3 +143,20 @@ h256 eth::sha3(bytesConstRef _input) sha3(_input, bytesRef(&ret[0], 32)); return ret; } + +Address eth::toPublic(h256 _private) +{ + bytes pubkey(65); + int pubkeylen = 65; + int ret = secp256k1_ecdsa_seckey_verify(_private.data()); + if (!ret) + return Address(); + ret = secp256k1_ecdsa_pubkey_create(pubkey.data(), &pubkeylen, _private.data(), 1); + if (!ret) + return Address(); + pubkey.resize(pubkeylen); + ret = secp256k1_ecdsa_pubkey_verify(pubkey.data(), pubkey.size()); + if (!ret) + return Address(); + return left160(eth::sha3(bytesConstRef(&pubkey).cropped(1))); +} diff --git a/libethereum/Common.h b/libethereum/Common.h index 30df2d810..2388a2042 100644 --- a/libethereum/Common.h +++ b/libethereum/Common.h @@ -313,5 +313,10 @@ inline bytes sha3Bytes(std::string const& _input) { return sha3Bytes((std::strin inline bytes sha3Bytes(bytes const& _input) { return sha3Bytes((bytes*)&_input); } h256 sha3(bytesConstRef _input); inline h256 sha3(bytes const& _input) { return sha3(bytesConstRef((bytes*)&_input)); } +inline h256 sha3(std::string const& _input) { return sha3(bytesConstRef(_input)); } + +/// Convert a private key into the public key equivalent. +/// @returns 0 if it's not a valid private key. +Address toPublic(h256 _private); } diff --git a/libethereum/State.cpp b/libethereum/State.cpp index 54ce6deb4..1a35bf5c7 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -447,6 +447,14 @@ void State::execute(Transaction const& _t, Address _sender) } } +// Convert from a 256-bit integer stack/memory entry into a 160-bit Address hash. +// Currently we just pull out the left (high-order in BE) 160-bits. +// TODO: check that this is correct. +inline Address asAddress(u256 _item) +{ + return left160(h256(_item)); +} + void State::execute(Address _myAddress, Address _txSender, u256 _txValue, u256 _txFee, u256s const& _txData, u256* _totalFee) { std::vector stack; @@ -892,14 +900,14 @@ void State::execute(Address _myAddress, Address _txSender, u256 _txValue, u256 _ require(2); auto memoryAddress = stack.back(); stack.pop_back(); - Address contractAddress = left160(stack.back()); + Address contractAddress = asAddress(stack.back()); stack.back() = contractMemory(contractAddress, memoryAddress); break; } case Instruction::BALANCE: { require(1); - stack.back() = balance(low160(stack.back())); + stack.back() = balance(asAddress(stack.back())); break; } case Instruction::MKTX: @@ -907,7 +915,7 @@ void State::execute(Address _myAddress, Address _txSender, u256 _txValue, u256 _ require(4); Transaction t; - t.receiveAddress = left160(stack.back()); + t.receiveAddress = asAddress(stack.back()); stack.pop_back(); t.value = stack.back(); stack.pop_back(); @@ -933,7 +941,7 @@ void State::execute(Address _myAddress, Address _txSender, u256 _txValue, u256 _ case Instruction::SUICIDE: { require(1); - Address dest = left160(stack.back()); + Address dest = asAddress(stack.back()); // TODO: easy once we have the local cache of memory in place. u256 minusVoidFee = 0;//m_current[_myAddress].memory().size() * c_memoryFee; addBalance(dest, balance(_myAddress) + minusVoidFee);