From f567f89b994bf28f908410223084a6702d05d156 Mon Sep 17 00:00:00 2001
From: obscuren <geffobscura@gmail.com>
Date: Thu, 20 Mar 2014 23:38:16 +0100
Subject: Added address to account and contract

Contract and account now both have an address field or method for the
sake of simplicity.
---
 ethchain/closure.go  |  1 +
 ethchain/contract.go | 38 +++++++++++++++++++++++++-------------
 ethchain/state.go    |  7 ++++---
 ethchain/vm.go       |  7 +++----
 ethchain/vm_test.go  | 11 +++++------
 5 files changed, 38 insertions(+), 26 deletions(-)

diff --git a/ethchain/closure.go b/ethchain/closure.go
index 9453ce22c..0eef866d0 100644
--- a/ethchain/closure.go
+++ b/ethchain/closure.go
@@ -15,6 +15,7 @@ type ClosureBody interface {
 	Callee
 	ethutil.RlpEncodable
 	GetMem(int64) *ethutil.Value
+	Address() []byte
 }
 
 // Basic inline closure object which implement the 'closure' interface
diff --git a/ethchain/contract.go b/ethchain/contract.go
index 10c5e2df6..93d2b68ba 100644
--- a/ethchain/contract.go
+++ b/ethchain/contract.go
@@ -9,26 +9,22 @@ type Contract struct {
 	Amount *big.Int
 	Nonce  uint64
 	//state  *ethutil.Trie
-	state *State
+	state   *State
+	address []byte
 }
 
-func NewContract(Amount *big.Int, root []byte) *Contract {
-	contract := &Contract{Amount: Amount, Nonce: 0}
+func NewContract(address []byte, Amount *big.Int, root []byte) *Contract {
+	contract := &Contract{address: address, Amount: Amount, Nonce: 0}
 	contract.state = NewState(ethutil.NewTrie(ethutil.Config.Db, string(root)))
 
 	return contract
 }
 
-func (c *Contract) RlpEncode() []byte {
-	return ethutil.Encode([]interface{}{c.Amount, c.Nonce, c.state.trie.Root})
-}
-
-func (c *Contract) RlpDecode(data []byte) {
-	decoder := ethutil.NewValueFromBytes(data)
+func NewContractFromBytes(address, data []byte) *Contract {
+	contract := &Contract{address: address}
+	contract.RlpDecode(data)
 
-	c.Amount = decoder.Get(0).BigInt()
-	c.Nonce = decoder.Get(1).Uint()
-	c.state = NewState(ethutil.NewTrie(ethutil.Config.Db, decoder.Get(2).Interface()))
+	return contract
 }
 
 func (c *Contract) Addr(addr []byte) *ethutil.Value {
@@ -54,13 +50,29 @@ func (c *Contract) ReturnGas(val *big.Int, state *State) {
 	c.Amount.Add(c.Amount, val)
 }
 
+func (c *Contract) Address() []byte {
+	return c.address
+}
+
+func (c *Contract) RlpEncode() []byte {
+	return ethutil.Encode([]interface{}{c.Amount, c.Nonce, c.state.trie.Root})
+}
+
+func (c *Contract) RlpDecode(data []byte) {
+	decoder := ethutil.NewValueFromBytes(data)
+
+	c.Amount = decoder.Get(0).BigInt()
+	c.Nonce = decoder.Get(1).Uint()
+	c.state = NewState(ethutil.NewTrie(ethutil.Config.Db, decoder.Get(2).Interface()))
+}
+
 func MakeContract(tx *Transaction, state *State) *Contract {
 	// Create contract if there's no recipient
 	if tx.IsContract() {
 		addr := tx.Hash()[12:]
 
 		value := tx.Value
-		contract := NewContract(value, []byte(""))
+		contract := NewContract(addr, value, []byte(""))
 		state.trie.Update(string(addr), string(contract.RlpEncode()))
 		for i, val := range tx.Data {
 			if len(val) > 0 {
diff --git a/ethchain/state.go b/ethchain/state.go
index b6750d62d..c9b35da21 100644
--- a/ethchain/state.go
+++ b/ethchain/state.go
@@ -63,8 +63,7 @@ func (s *State) GetContract(addr []byte) *Contract {
 	}
 
 	// build contract
-	contract := &Contract{}
-	contract.RlpDecode([]byte(data))
+	contract := NewContractFromBytes(addr, []byte(data))
 
 	// Check if there's a cached state for this contract
 	cachedState := s.states[string(addr)]
@@ -78,7 +77,9 @@ func (s *State) GetContract(addr []byte) *Contract {
 	return contract
 }
 
-func (s *State) UpdateContract(addr []byte, contract *Contract) {
+func (s *State) UpdateContract(contract *Contract) {
+	addr := contract.Address()
+
 	s.states[string(addr)] = contract.state
 	s.trie.Update(string(addr), string(contract.RlpEncode()))
 }
diff --git a/ethchain/vm.go b/ethchain/vm.go
index 3d85e2c09..ba19231cc 100644
--- a/ethchain/vm.go
+++ b/ethchain/vm.go
@@ -23,14 +23,12 @@ type Vm struct {
 }
 
 type RuntimeVars struct {
-	address     []byte
+	origin      []byte
 	blockNumber uint64
-	sender      []byte
 	prevHash    []byte
 	coinbase    []byte
 	time        int64
 	diff        *big.Int
-	txValue     *big.Int
 	txData      []string
 }
 
@@ -108,6 +106,7 @@ func (vm *Vm) RunClosure(closure *Closure) []byte {
 			closure := NewClosure(closure, contract, vm.state, gas, value)
 			// Executer the closure and get the return value (if any)
 			ret := closure.Call(vm, nil)
+
 			mem.Set(retOffset.Int64(), retSize.Int64(), ret)
 		case oRETURN:
 			size, offset := stack.Popn()
@@ -501,7 +500,7 @@ func makeInlineTx(addr []byte, value, from, length *big.Int, contract *Contract,
 	tx := NewTransaction(addr, value, dataItems)
 	if tx.IsContract() {
 		contract := MakeContract(tx, state)
-		state.UpdateContract(tx.Hash()[12:], contract)
+		state.UpdateContract(contract)
 	} else {
 		account := state.GetAccount(tx.Recipient)
 		account.Amount.Add(account.Amount, tx.Value)
diff --git a/ethchain/vm_test.go b/ethchain/vm_test.go
index 30c8a110e..1dca5cfb7 100644
--- a/ethchain/vm_test.go
+++ b/ethchain/vm_test.go
@@ -130,7 +130,7 @@ func TestRun3(t *testing.T) {
 	addr := tx.Hash()[12:]
 	fmt.Printf("addr contract %x\n", addr)
 	contract := MakeContract(tx, state)
-	state.UpdateContract(addr, contract)
+	state.UpdateContract(contract)
 
 	callerScript := Compile([]string{
 		"PUSH", "62", // ret size
@@ -143,21 +143,20 @@ func TestRun3(t *testing.T) {
 		"CALL",
 	})
 	callerTx := NewTransaction(ContractAddr, ethutil.Big("100000000000000000000000000000000000000000000000000"), callerScript)
-	callerAddr := callerTx.Hash()[12:]
 
+	// Contract addr as test address
 	account := NewAccount(ContractAddr, big.NewInt(10000000))
 	callerClosure := NewClosure(account, MakeContract(callerTx, state), state, big.NewInt(1000000000), new(big.Int))
 
 	vm := NewVm(state, RuntimeVars{
-		address:     callerAddr,
+		origin:      account.Address,
 		blockNumber: 1,
-		sender:      ethutil.FromHex("cd1722f3947def4cf144679da39c4c32bdc35681"),
 		prevHash:    ethutil.FromHex("5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"),
 		coinbase:    ethutil.FromHex("2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"),
 		time:        1,
 		diff:        big.NewInt(256),
-		txValue:     big.NewInt(10000),
-		txData:      nil,
+		// XXX Tx data? Could be just an argument to the closure instead
+		txData: nil,
 	})
 	callerClosure.Call(vm, nil)
 }
-- 
cgit v1.2.3