aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorobscuren <geffobscura@gmail.com>2014-03-21 06:38:16 +0800
committerobscuren <geffobscura@gmail.com>2014-03-21 06:38:16 +0800
commitf567f89b994bf28f908410223084a6702d05d156 (patch)
tree1ec45639e8ec6787d1d97ec59c2bd78a7f90d9b0
parent7705b23f248156878d00c301fbbadafedaf7e3d2 (diff)
downloadgo-tangerine-f567f89b994bf28f908410223084a6702d05d156.tar
go-tangerine-f567f89b994bf28f908410223084a6702d05d156.tar.gz
go-tangerine-f567f89b994bf28f908410223084a6702d05d156.tar.bz2
go-tangerine-f567f89b994bf28f908410223084a6702d05d156.tar.lz
go-tangerine-f567f89b994bf28f908410223084a6702d05d156.tar.xz
go-tangerine-f567f89b994bf28f908410223084a6702d05d156.tar.zst
go-tangerine-f567f89b994bf28f908410223084a6702d05d156.zip
Added address to account and contract
Contract and account now both have an address field or method for the sake of simplicity.
-rw-r--r--ethchain/closure.go1
-rw-r--r--ethchain/contract.go38
-rw-r--r--ethchain/state.go7
-rw-r--r--ethchain/vm.go7
-rw-r--r--ethchain/vm_test.go11
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)
}