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

View File

@ -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) {
// If there's no recipient, it's a contract
// Check if this is a contract creation traction and if so
// create a contract of this tx.
// TODO COMMENT THIS SECTION
/*
Applies transactions to the given state and creates new
state objects where needed.
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)
if tx.IsContract() {
err := sm.Ethereum.TxPool().ProcessTransaction(tx, state, false)
// Apply the transaction to the current state
err := sm.Ethereum.TxPool().ProcessTransaction(tx, state, false)
if tx.CreatesContract() {
if err == nil {
// Create a new state object and the transaction
// as it's data provider.
contract := sm.MakeStateObject(state, tx)
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)
if err != nil {
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)
}
} else {
err := sm.Ethereum.TxPool().ProcessTransaction(tx, state, false)
contract := state.GetStateObject(tx.Recipient)
if err == nil && contract != nil && len(contract.Script()) > 0 {
sm.EvalScript(state, contract.Script(), contract, tx, block)
// Find the state object at the "recipient" address. If
// there's an object attempt to run the script.
stateObject := state.GetStateObject(tx.Recipient)
if err == nil && stateObject != nil && len(stateObject.Script()) > 0 {
sm.EvalScript(state, stateObject.Script(), stateObject, tx, block)
} else if err != nil {
return nil, fmt.Errorf("[STATE] process:", err)
}

View File

@ -57,10 +57,15 @@ func (tx *Transaction) Hash() []byte {
return ethutil.Sha3Bin(ethutil.NewValue(data).Encode())
}
func (tx *Transaction) IsContract() bool {
func (tx *Transaction) CreatesContract() bool {
return tx.contractCreation
}
/* Depricated */
func (tx *Transaction) IsContract() bool {
return tx.CreatesContract()
}
func (tx *Transaction) CreationAddress() []byte {
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.r = decoder.Get(7).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
@ -173,7 +181,7 @@ func (tx *Transaction) String() string {
S: 0x%x
`,
tx.Hash(),
len(tx.Recipient) == 1,
len(tx.Recipient) == 0,
tx.Sender(),
tx.Recipient,
tx.Nonce,

View File

@ -1,6 +1,5 @@
package ethchain
/*
import (
_ "bytes"
"fmt"
@ -13,60 +12,33 @@ import (
)
func TestRun4(t *testing.T) {
ethutil.ReadConfig("", ethutil.LogStd)
ethutil.ReadConfig("", ethutil.LogStd, "")
db, _ := ethdb.NewMemDatabase()
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(`
// Check if there's any cash in the initial store
if this.store[1000] == 0 {
this.store[1000] = 10**20
}
this.store[1001] = this.value() * 20
this.store[this.origin()] = this.store[this.origin()] + 1000
if this.store[1001] > 20 {
this.store[1001] = 10^50
}
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
this.store[this.origin()] = 10**20
hello := "world"
return lambda {
big to = this.data[0]
big from = this.origin()
big value = this.data[1]
if this.store[from] >= value {
this.store[from] = this.store[from] - value
this.store[to] = this.store[to] + value
}
}
`), false)
if err != nil {
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
gas := big.NewInt(1000)
@ -79,7 +51,7 @@ func TestRun4(t *testing.T) {
fmt.Println(err)
}
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{
Origin: account.Address(),
@ -89,10 +61,10 @@ func TestRun4(t *testing.T) {
Time: 1,
Diff: big.NewInt(256),
})
_, e = callerClosure.Call(vm, nil, nil)
var ret []byte
ret, e = callerClosure.Call(vm, nil, nil)
if e != nil {
fmt.Println("error", e)
}
fmt.Println("account.Amount =", account.Amount)
fmt.Println(ret)
}
*/

View File

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

View File

@ -137,7 +137,7 @@ func (p *EthereumApi) Create(args *NewTxArgs, reply *string) error {
if err != nil {
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)
return nil
}