From f93bb35c021daa25bb4a61dee3dd5b73311f2c49 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Sat, 21 Mar 2015 02:44:20 -0700 Subject: [PATCH] rpc: return tx hash, creates contract, contract addr in broadcast (required some helper functions). Closes #30 --- merkle/simple_tree.go | 17 +++++++++++------ rpc/mempool.go | 19 ++++++++++++++++++- state/vm_app_state.go | 16 ++++++++++++---- 3 files changed, 41 insertions(+), 11 deletions(-) diff --git a/merkle/simple_tree.go b/merkle/simple_tree.go index f31e36e5..bdc9164d 100644 --- a/merkle/simple_tree.go +++ b/merkle/simple_tree.go @@ -61,16 +61,21 @@ func HashFromHashes(hashes [][]byte) []byte { func HashFromBinaries(items []interface{}) []byte { hashes := [][]byte{} for _, item := range items { - hasher, n, err := sha256.New(), new(int64), new(error) - binary.WriteBinary(item, hasher, n, err) - if *err != nil { - panic(err) - } - hashes = append(hashes, hasher.Sum(nil)) + hashes = append(hashes, HashFromBinary(item)) } return HashFromHashes(hashes) } +// General Convenience +func HashFromBinary(item interface{}) []byte { + hasher, n, err := sha256.New(), new(int64), new(error) + binary.WriteBinary(item, hasher, n, err) + if *err != nil { + panic(err) + } + return hasher.Sum(nil) +} + // Convenience for HashFromHashes. func HashFromHashables(items []Hashable) []byte { hashes := [][]byte{} diff --git a/rpc/mempool.go b/rpc/mempool.go index d047dbe5..0296ee69 100644 --- a/rpc/mempool.go +++ b/rpc/mempool.go @@ -6,6 +6,8 @@ import ( "github.com/tendermint/tendermint/binary" blk "github.com/tendermint/tendermint/block" . "github.com/tendermint/tendermint/common" + "github.com/tendermint/tendermint/merkle" + "github.com/tendermint/tendermint/state" ) func BroadcastTxHandler(w http.ResponseWriter, r *http.Request) { @@ -24,7 +26,22 @@ func BroadcastTxHandler(w http.ResponseWriter, r *http.Request) { return } - WriteAPIResponse(w, API_OK, "") + txHash := merkle.HashFromBinary(tx) + var createsContract bool + var contractAddr []byte + + if callTx, ok := tx.(*blk.CallTx); ok { + if callTx.Address == nil { + createsContract = true + contractAddr = state.NewContractAddress(callTx.Input.Address, uint64(callTx.Input.Sequence)) + } + } + + WriteAPIResponse(w, API_OK, struct { + TxHash []byte + CreatesContract bool + ContractAddr []byte + }{txHash, createsContract, contractAddr}) return } diff --git a/state/vm_app_state.go b/state/vm_app_state.go index ef696c96..643f30f8 100644 --- a/state/vm_app_state.go +++ b/state/vm_app_state.go @@ -113,10 +113,8 @@ func (vas *VMAppState) CreateAccount(creator *vm.Account) (*vm.Account, error) { // Generate an address nonce := creator.Nonce creator.Nonce += 1 - temp := make([]byte, 32+8) - copy(temp, creator.Address[:]) - vm.PutUint64(temp[32:], nonce) - addr := vm.RightPadWord(sha3.Sha3(temp)[:20]) + + addr := vm.RightPadWord(NewContractAddress(creator.Address[:], nonce)) // Create account from address. account, deleted := unpack(vas.accounts[addr.String()]) @@ -238,3 +236,13 @@ func (vas *VMAppState) Sync() { func (vas *VMAppState) AddLog(log *vm.Log) { vas.logs = append(vas.logs, log) } + +//----------------------------------------------------------------------------- + +// Convenience function to return address of new contract +func NewContractAddress(caller []byte, nonce uint64) []byte { + temp := make([]byte, 32+8) + copy(temp, caller) + vm.PutUint64(temp[32:], nonce) + return sha3.Sha3(temp)[:20] +}