The body of contracts are now returned instead

This commit is contained in:
obscuren 2014-05-25 14:13:54 +01:00
parent 99fa9afaf1
commit 81ef40010f
5 changed files with 86 additions and 82 deletions

@ -120,16 +120,27 @@ func (sm *StateManager) ApplyTransactions(state *State, block *Block, txs []*Tra
} }
func (sm *StateManager) ApplyTransaction(state *State, block *Block, tx *Transaction) (*big.Int, error) { func (sm *StateManager) ApplyTransaction(state *State, block *Block, tx *Transaction) (*big.Int, error) {
// If there's no recipient, it's a contract /*
// Check if this is a contract creation traction and if so Applies transactions to the given state and creates new
// create a contract of this tx. state objects where needed.
// TODO COMMENT THIS SECTION
If said objects needs to be created
run the initialization script provided by the transaction and
assume there's a return value. The return value will be set to
the script section of the state object.
*/
totalGasUsed := big.NewInt(0) totalGasUsed := big.NewInt(0)
if tx.IsContract() { // Apply the transaction to the current state
err := sm.Ethereum.TxPool().ProcessTransaction(tx, state, false) err := sm.Ethereum.TxPool().ProcessTransaction(tx, state, false)
if tx.CreatesContract() {
if err == nil { if err == nil {
// Create a new state object and the transaction
// as it's data provider.
contract := sm.MakeStateObject(state, tx) contract := sm.MakeStateObject(state, tx)
if contract != nil { if contract != nil {
// Evaluate the initialization script
// and use the return value as the
// script section for the state object.
script, err := sm.EvalScript(state, contract.Init(), contract, tx, block) script, err := sm.EvalScript(state, contract.Init(), contract, tx, block)
if err != nil { if err != nil {
return nil, fmt.Errorf("[STATE] Error during init script run %v", err) return nil, fmt.Errorf("[STATE] Error during init script run %v", err)
@ -143,10 +154,11 @@ func (sm *StateManager) ApplyTransaction(state *State, block *Block, tx *Transac
return nil, fmt.Errorf("[STATE] contract creation tx:", err) return nil, fmt.Errorf("[STATE] contract creation tx:", err)
} }
} else { } else {
err := sm.Ethereum.TxPool().ProcessTransaction(tx, state, false) // Find the state object at the "recipient" address. If
contract := state.GetStateObject(tx.Recipient) // there's an object attempt to run the script.
if err == nil && contract != nil && len(contract.Script()) > 0 { stateObject := state.GetStateObject(tx.Recipient)
sm.EvalScript(state, contract.Script(), contract, tx, block) if err == nil && stateObject != nil && len(stateObject.Script()) > 0 {
sm.EvalScript(state, stateObject.Script(), stateObject, tx, block)
} else if err != nil { } else if err != nil {
return nil, fmt.Errorf("[STATE] process:", err) return nil, fmt.Errorf("[STATE] process:", err)
} }

@ -57,10 +57,15 @@ func (tx *Transaction) Hash() []byte {
return ethutil.Sha3Bin(ethutil.NewValue(data).Encode()) return ethutil.Sha3Bin(ethutil.NewValue(data).Encode())
} }
func (tx *Transaction) IsContract() bool { func (tx *Transaction) CreatesContract() bool {
return tx.contractCreation return tx.contractCreation
} }
/* Depricated */
func (tx *Transaction) IsContract() bool {
return tx.CreatesContract()
}
func (tx *Transaction) CreationAddress() []byte { func (tx *Transaction) CreationAddress() []byte {
return ethutil.Sha3Bin(ethutil.NewValue([]interface{}{tx.Sender(), tx.Nonce}).Encode())[12:] return ethutil.Sha3Bin(ethutil.NewValue([]interface{}{tx.Sender(), tx.Nonce}).Encode())[12:]
} }
@ -139,6 +144,9 @@ func (tx *Transaction) RlpValueDecode(decoder *ethutil.Value) {
tx.v = byte(decoder.Get(6).Uint()) tx.v = byte(decoder.Get(6).Uint())
tx.r = decoder.Get(7).Bytes() tx.r = decoder.Get(7).Bytes()
tx.s = decoder.Get(8).Bytes() tx.s = decoder.Get(8).Bytes()
if len(tx.Recipient) == 0 {
tx.contractCreation = true
}
/* /*
// If the list is of length 10 it's a contract creation tx // If the list is of length 10 it's a contract creation tx
@ -173,7 +181,7 @@ func (tx *Transaction) String() string {
S: 0x%x S: 0x%x
`, `,
tx.Hash(), tx.Hash(),
len(tx.Recipient) == 1, len(tx.Recipient) == 0,
tx.Sender(), tx.Sender(),
tx.Recipient, tx.Recipient,
tx.Nonce, tx.Nonce,

@ -1,6 +1,5 @@
package ethchain package ethchain
/*
import ( import (
_ "bytes" _ "bytes"
"fmt" "fmt"
@ -13,60 +12,33 @@ import (
) )
func TestRun4(t *testing.T) { func TestRun4(t *testing.T) {
ethutil.ReadConfig("", ethutil.LogStd) ethutil.ReadConfig("", ethutil.LogStd, "")
db, _ := ethdb.NewMemDatabase() db, _ := ethdb.NewMemDatabase()
state := NewState(ethutil.NewTrie(db, "")) state := NewState(ethutil.NewTrie(db, ""))
script, err := mutan.Compile(strings.NewReader(`
int32 a = 10
int32 b = 20
if a > b {
int32 c = this.caller()
}
exit()
`), false)
tx := NewContractCreationTx(ethutil.Big("0"), ethutil.Big("1000"), ethutil.Big("100"), script, nil)
tx.Sign(ContractAddr)
addr := tx.CreationAddress()
contract := MakeContract(tx, state)
state.UpdateStateObject(contract)
fmt.Printf("%x\n", addr)
callerScript, err := mutan.Compile(strings.NewReader(` callerScript, err := mutan.Compile(strings.NewReader(`
// Check if there's any cash in the initial store this.store[this.origin()] = 10**20
if this.store[1000] == 0 { hello := "world"
this.store[1000] = 10**20
} return lambda {
big to = this.data[0]
big from = this.origin()
this.store[1001] = this.value() * 20 big value = this.data[1]
this.store[this.origin()] = this.store[this.origin()] + 1000
if this.store[from] >= value {
if this.store[1001] > 20 { this.store[from] = this.store[from] - value
this.store[1001] = 10^50 this.store[to] = this.store[to] + value
}
int8 ret = 0
int8 arg = 10
call(0xe6a12555fad1fb6eaaaed69001a87313d1fd7b54, 0, 100, arg, ret)
big t
for int8 i = 0; i < 10; i++ {
t = i
}
if 10 > 20 {
int8 shouldnt = 2
} else {
int8 should = 1
} }
}
`), false) `), false)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
} }
fmt.Println(Disassemble(callerScript))
callerTx := NewContractCreationTx(ethutil.Big("0"), ethutil.Big("1000"), ethutil.Big("100"), callerScript, nil) callerTx := NewContractCreationTx(ethutil.Big("0"), ethutil.Big("1000"), ethutil.Big("100"), callerScript)
callerTx.Sign([]byte("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"))
// Contract addr as test address // Contract addr as test address
gas := big.NewInt(1000) gas := big.NewInt(1000)
@ -79,7 +51,7 @@ func TestRun4(t *testing.T) {
fmt.Println(err) fmt.Println(err)
} }
fmt.Println("account.Amount =", account.Amount) fmt.Println("account.Amount =", account.Amount)
callerClosure := NewClosure(account, c, c.script, state, gas, gasPrice) callerClosure := NewClosure(account, c, callerScript, state, gas, gasPrice)
vm := NewVm(state, nil, RuntimeVars{ vm := NewVm(state, nil, RuntimeVars{
Origin: account.Address(), Origin: account.Address(),
@ -89,10 +61,10 @@ func TestRun4(t *testing.T) {
Time: 1, Time: 1,
Diff: big.NewInt(256), Diff: big.NewInt(256),
}) })
_, e = callerClosure.Call(vm, nil, nil) var ret []byte
ret, e = callerClosure.Call(vm, nil, nil)
if e != nil { if e != nil {
fmt.Println("error", e) fmt.Println("error", e)
} }
fmt.Println("account.Amount =", account.Amount) fmt.Println(ret)
} }
*/

@ -87,14 +87,14 @@ func (lib *PEthereum) SecretToAddress(key string) string {
} }
func (lib *PEthereum) Transact(key, recipient, valueStr, gasStr, gasPriceStr, dataStr string) (*PReceipt, error) { func (lib *PEthereum) Transact(key, recipient, valueStr, gasStr, gasPriceStr, dataStr string) (*PReceipt, error) {
return lib.createTx(key, recipient, valueStr, gasStr, gasPriceStr, dataStr, "") return lib.createTx(key, recipient, valueStr, gasStr, gasPriceStr, dataStr)
} }
func (lib *PEthereum) Create(key, valueStr, gasStr, gasPriceStr, initStr, bodyStr string) (*PReceipt, error) { func (lib *PEthereum) Create(key, valueStr, gasStr, gasPriceStr, script string) (*PReceipt, error) {
return lib.createTx(key, "", valueStr, gasStr, gasPriceStr, initStr, bodyStr) return lib.createTx(key, "", valueStr, gasStr, gasPriceStr, script)
} }
func (lib *PEthereum) createTx(key, recipient, valueStr, gasStr, gasPriceStr, initStr, scriptStr string) (*PReceipt, error) { func (lib *PEthereum) createTx(key, recipient, valueStr, gasStr, gasPriceStr, scriptStr string) (*PReceipt, error) {
var hash []byte var hash []byte
var contractCreation bool var contractCreation bool
if len(recipient) == 0 { if len(recipient) == 0 {
@ -121,35 +121,47 @@ func (lib *PEthereum) createTx(key, recipient, valueStr, gasStr, gasPriceStr, in
var tx *ethchain.Transaction var tx *ethchain.Transaction
// Compile and assemble the given data // Compile and assemble the given data
if contractCreation { if contractCreation {
var initScript, mainScript []byte /*
var initScript, mainScript []byte
var err error
if ethutil.IsHex(initStr) {
initScript = ethutil.FromHex(initStr[2:])
} else {
initScript, err = ethutil.Compile(initStr)
if err != nil {
return nil, err
}
}
if ethutil.IsHex(scriptStr) {
mainScript = ethutil.FromHex(scriptStr[2:])
} else {
mainScript, err = ethutil.Compile(scriptStr)
if err != nil {
return nil, err
}
}
script := ethchain.AppendScript(initScript, mainScript)
*/
var script []byte
var err error var err error
if ethutil.IsHex(initStr) {
initScript = ethutil.FromHex(initStr[2:])
} else {
initScript, err = ethutil.Compile(initStr)
if err != nil {
return nil, err
}
}
if ethutil.IsHex(scriptStr) { if ethutil.IsHex(scriptStr) {
mainScript = ethutil.FromHex(scriptStr[2:]) script = ethutil.FromHex(scriptStr)
} else { } else {
mainScript, err = ethutil.Compile(scriptStr) script, err = ethutil.Compile(scriptStr)
if err != nil { if err != nil {
return nil, err return nil, err
} }
} }
script := ethchain.AppendScript(initScript, mainScript)
tx = ethchain.NewContractCreationTx(value, gas, gasPrice, script) tx = ethchain.NewContractCreationTx(value, gas, gasPrice, script)
} else { } else {
// Just in case it was submitted as a 0x prefixed string // Just in case it was submitted as a 0x prefixed string
if len(initStr) > 0 && initStr[0:2] == "0x" { if len(scriptStr) > 0 && scriptStr[0:2] == "0x" {
initStr = initStr[2:len(initStr)] scriptStr = scriptStr[2:len(scriptStr)]
} }
tx = ethchain.NewTransactionMessage(hash, value, gas, gasPrice, ethutil.FromHex(initStr)) tx = ethchain.NewTransactionMessage(hash, value, gas, gasPrice, ethutil.FromHex(scriptStr))
} }
acc := lib.stateManager.TransState().GetStateObject(keyPair.Address()) acc := lib.stateManager.TransState().GetStateObject(keyPair.Address())

@ -137,7 +137,7 @@ func (p *EthereumApi) Create(args *NewTxArgs, reply *string) error {
if err != nil { if err != nil {
return err return err
} }
result, _ := p.ethp.Create(p.ethp.GetKey().PrivateKey, args.Value, args.Gas, args.GasPrice, args.Init, args.Body) result, _ := p.ethp.Create(p.ethp.GetKey().PrivateKey, args.Value, args.Gas, args.GasPrice, args.Body)
*reply = NewSuccessRes(result) *reply = NewSuccessRes(result)
return nil return nil
} }