Added address to account and contract
Contract and account now both have an address field or method for the sake of simplicity.
This commit is contained in:
parent
7705b23f24
commit
f567f89b99
@ -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 {
|
|||||||
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) {
|
return contract
|
||||||
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 (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) {
|
|||||||
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 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 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 {
|
|||||||
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 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
|||||||
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,
|
|||||||
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) {
|
|||||||
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) {
|
|||||||
"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)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user