aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ethchain/state_manager.go32
-rw-r--r--ethchain/transaction.go12
-rw-r--r--ethchain/vm_test.go64
-rw-r--r--ethpub/pub.go52
-rw-r--r--ethrpc/packages.go2
5 files changed, 83 insertions, 79 deletions
diff --git a/ethchain/state_manager.go b/ethchain/state_manager.go
index 4f009b6d3..2d2a32e2f 100644
--- a/ethchain/state_manager.go
+++ b/ethchain/state_manager.go
@@ -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)
}
diff --git a/ethchain/transaction.go b/ethchain/transaction.go
index 25d63879b..2c5615f99 100644
--- a/ethchain/transaction.go
+++ b/ethchain/transaction.go
@@ -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,
diff --git a/ethchain/vm_test.go b/ethchain/vm_test.go
index 2ec70536a..520f9a2ed 100644
--- a/ethchain/vm_test.go
+++ b/ethchain/vm_test.go
@@ -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
+ this.store[this.origin()] = 10**20
+ hello := "world"
- 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
- }
+ return lambda {
+ big to = this.data[0]
+ big from = this.origin()
+ big value = this.data[1]
- if 10 > 20 {
- int8 shouldnt = 2
- } else {
- int8 should = 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)
}
-*/
diff --git a/ethpub/pub.go b/ethpub/pub.go
index e726c66f3..b75d3abc8 100644
--- a/ethpub/pub.go
+++ b/ethpub/pub.go
@@ -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 err error
- if ethutil.IsHex(initStr) {
- initScript = ethutil.FromHex(initStr[2:])
- } else {
- initScript, err = ethutil.Compile(initStr)
- if err != nil {
- return nil, err
+ /*
+ 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(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())
diff --git a/ethrpc/packages.go b/ethrpc/packages.go
index 87cfc99b2..1c4fb99f6 100644
--- a/ethrpc/packages.go
+++ b/ethrpc/packages.go
@@ -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
}