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 {
Callee
ethutil.RlpEncodable
GetMem(int64) *ethutil.Value
Address() []byte
}
// Basic inline closure object which implement the 'closure' interface
......
......@@ -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 {
......
......@@ -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()))
}
......
......@@ -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)
......
......@@ -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)
}
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