Commit f567f89b authored by obscuren's avatar obscuren

Added address to account and contract

Contract and account now both have an address field or method for the
sake of simplicity.
parent 7705b23f
...@@ -15,6 +15,7 @@ type ClosureBody interface { ...@@ -15,6 +15,7 @@ type ClosureBody interface {
Callee Callee
ethutil.RlpEncodable ethutil.RlpEncodable
GetMem(int64) *ethutil.Value GetMem(int64) *ethutil.Value
Address() []byte
} }
// Basic inline closure object which implement the 'closure' interface // Basic inline closure object which implement the 'closure' interface
......
...@@ -9,26 +9,22 @@ type Contract struct { ...@@ -9,26 +9,22 @@ type Contract struct {
Amount *big.Int Amount *big.Int
Nonce uint64 Nonce uint64
//state *ethutil.Trie //state *ethutil.Trie
state *State state *State
address []byte
} }
func NewContract(Amount *big.Int, root []byte) *Contract { func NewContract(address []byte, Amount *big.Int, root []byte) *Contract {
contract := &Contract{Amount: Amount, Nonce: 0} contract := &Contract{address: address, Amount: Amount, Nonce: 0}
contract.state = NewState(ethutil.NewTrie(ethutil.Config.Db, string(root))) contract.state = NewState(ethutil.NewTrie(ethutil.Config.Db, string(root)))
return contract return contract
} }
func (c *Contract) RlpEncode() []byte { func NewContractFromBytes(address, data []byte) *Contract {
return ethutil.Encode([]interface{}{c.Amount, c.Nonce, c.state.trie.Root}) contract := &Contract{address: address}
} contract.RlpDecode(data)
func (c *Contract) RlpDecode(data []byte) {
decoder := ethutil.NewValueFromBytes(data)
c.Amount = decoder.Get(0).BigInt() return contract
c.Nonce = decoder.Get(1).Uint()
c.state = NewState(ethutil.NewTrie(ethutil.Config.Db, decoder.Get(2).Interface()))
} }
func (c *Contract) Addr(addr []byte) *ethutil.Value { func (c *Contract) Addr(addr []byte) *ethutil.Value {
...@@ -54,13 +50,29 @@ func (c *Contract) ReturnGas(val *big.Int, state *State) { ...@@ -54,13 +50,29 @@ func (c *Contract) ReturnGas(val *big.Int, state *State) {
c.Amount.Add(c.Amount, val) 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 { func MakeContract(tx *Transaction, state *State) *Contract {
// Create contract if there's no recipient // Create contract if there's no recipient
if tx.IsContract() { if tx.IsContract() {
addr := tx.Hash()[12:] addr := tx.Hash()[12:]
value := tx.Value value := tx.Value
contract := NewContract(value, []byte("")) contract := NewContract(addr, value, []byte(""))
state.trie.Update(string(addr), string(contract.RlpEncode())) state.trie.Update(string(addr), string(contract.RlpEncode()))
for i, val := range tx.Data { for i, val := range tx.Data {
if len(val) > 0 { if len(val) > 0 {
......
...@@ -63,8 +63,7 @@ func (s *State) GetContract(addr []byte) *Contract { ...@@ -63,8 +63,7 @@ func (s *State) GetContract(addr []byte) *Contract {
} }
// build contract // build contract
contract := &Contract{} contract := NewContractFromBytes(addr, []byte(data))
contract.RlpDecode([]byte(data))
// Check if there's a cached state for this contract // Check if there's a cached state for this contract
cachedState := s.states[string(addr)] cachedState := s.states[string(addr)]
...@@ -78,7 +77,9 @@ func (s *State) GetContract(addr []byte) *Contract { ...@@ -78,7 +77,9 @@ func (s *State) GetContract(addr []byte) *Contract {
return 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.states[string(addr)] = contract.state
s.trie.Update(string(addr), string(contract.RlpEncode())) s.trie.Update(string(addr), string(contract.RlpEncode()))
} }
......
...@@ -23,14 +23,12 @@ type Vm struct { ...@@ -23,14 +23,12 @@ type Vm struct {
} }
type RuntimeVars struct { type RuntimeVars struct {
address []byte origin []byte
blockNumber uint64 blockNumber uint64
sender []byte
prevHash []byte prevHash []byte
coinbase []byte coinbase []byte
time int64 time int64
diff *big.Int diff *big.Int
txValue *big.Int
txData []string txData []string
} }
...@@ -108,6 +106,7 @@ func (vm *Vm) RunClosure(closure *Closure) []byte { ...@@ -108,6 +106,7 @@ func (vm *Vm) RunClosure(closure *Closure) []byte {
closure := NewClosure(closure, contract, vm.state, gas, value) closure := NewClosure(closure, contract, vm.state, gas, value)
// Executer the closure and get the return value (if any) // Executer the closure and get the return value (if any)
ret := closure.Call(vm, nil) ret := closure.Call(vm, nil)
mem.Set(retOffset.Int64(), retSize.Int64(), ret) mem.Set(retOffset.Int64(), retSize.Int64(), ret)
case oRETURN: case oRETURN:
size, offset := stack.Popn() size, offset := stack.Popn()
...@@ -501,7 +500,7 @@ func makeInlineTx(addr []byte, value, from, length *big.Int, contract *Contract, ...@@ -501,7 +500,7 @@ func makeInlineTx(addr []byte, value, from, length *big.Int, contract *Contract,
tx := NewTransaction(addr, value, dataItems) tx := NewTransaction(addr, value, dataItems)
if tx.IsContract() { if tx.IsContract() {
contract := MakeContract(tx, state) contract := MakeContract(tx, state)
state.UpdateContract(tx.Hash()[12:], contract) state.UpdateContract(contract)
} else { } else {
account := state.GetAccount(tx.Recipient) account := state.GetAccount(tx.Recipient)
account.Amount.Add(account.Amount, tx.Value) account.Amount.Add(account.Amount, tx.Value)
......
...@@ -130,7 +130,7 @@ func TestRun3(t *testing.T) { ...@@ -130,7 +130,7 @@ func TestRun3(t *testing.T) {
addr := tx.Hash()[12:] addr := tx.Hash()[12:]
fmt.Printf("addr contract %x\n", addr) fmt.Printf("addr contract %x\n", addr)
contract := MakeContract(tx, state) contract := MakeContract(tx, state)
state.UpdateContract(addr, contract) state.UpdateContract(contract)
callerScript := Compile([]string{ callerScript := Compile([]string{
"PUSH", "62", // ret size "PUSH", "62", // ret size
...@@ -143,21 +143,20 @@ func TestRun3(t *testing.T) { ...@@ -143,21 +143,20 @@ func TestRun3(t *testing.T) {
"CALL", "CALL",
}) })
callerTx := NewTransaction(ContractAddr, ethutil.Big("100000000000000000000000000000000000000000000000000"), callerScript) callerTx := NewTransaction(ContractAddr, ethutil.Big("100000000000000000000000000000000000000000000000000"), callerScript)
callerAddr := callerTx.Hash()[12:]
// Contract addr as test address
account := NewAccount(ContractAddr, big.NewInt(10000000)) account := NewAccount(ContractAddr, big.NewInt(10000000))
callerClosure := NewClosure(account, MakeContract(callerTx, state), state, big.NewInt(1000000000), new(big.Int)) callerClosure := NewClosure(account, MakeContract(callerTx, state), state, big.NewInt(1000000000), new(big.Int))
vm := NewVm(state, RuntimeVars{ vm := NewVm(state, RuntimeVars{
address: callerAddr, origin: account.Address,
blockNumber: 1, blockNumber: 1,
sender: ethutil.FromHex("cd1722f3947def4cf144679da39c4c32bdc35681"),
prevHash: ethutil.FromHex("5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"), prevHash: ethutil.FromHex("5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"),
coinbase: ethutil.FromHex("2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"), coinbase: ethutil.FromHex("2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"),
time: 1, time: 1,
diff: big.NewInt(256), diff: big.NewInt(256),
txValue: big.NewInt(10000), // XXX Tx data? Could be just an argument to the closure instead
txData: nil, txData: nil,
}) })
callerClosure.Call(vm, nil) callerClosure.Call(vm, nil)
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment