forked from cerc-io/plugeth
Created generic message (easy for testing)
This commit is contained in:
parent
9e286e1c33
commit
db494170dc
@ -305,13 +305,13 @@ func (gui *Gui) insertTransaction(window string, tx *types.Transaction) {
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
ptx = xeth.NewJSTx(tx, pipe.World().State())
|
ptx = xeth.NewJSTx(tx, pipe.World().State())
|
||||||
send = nameReg.Storage(tx.Sender())
|
send = nameReg.Storage(tx.From())
|
||||||
rec = nameReg.Storage(tx.Recipient)
|
rec = nameReg.Storage(tx.To())
|
||||||
s, r string
|
s, r string
|
||||||
)
|
)
|
||||||
|
|
||||||
if tx.CreatesContract() {
|
if tx.CreatesContract() {
|
||||||
rec = nameReg.Storage(tx.CreationAddress(pipe.World().State()))
|
rec = nameReg.Storage(core.AddressFromMessage(tx))
|
||||||
}
|
}
|
||||||
|
|
||||||
if send.Len() != 0 {
|
if send.Len() != 0 {
|
||||||
@ -323,9 +323,9 @@ func (gui *Gui) insertTransaction(window string, tx *types.Transaction) {
|
|||||||
r = strings.Trim(rec.Str(), "\x00")
|
r = strings.Trim(rec.Str(), "\x00")
|
||||||
} else {
|
} else {
|
||||||
if tx.CreatesContract() {
|
if tx.CreatesContract() {
|
||||||
r = ethutil.Bytes2Hex(tx.CreationAddress(pipe.World().State()))
|
r = ethutil.Bytes2Hex(core.AddressFromMessage(tx))
|
||||||
} else {
|
} else {
|
||||||
r = ethutil.Bytes2Hex(tx.Recipient)
|
r = ethutil.Bytes2Hex(tx.To())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ptx.Sender = s
|
ptx.Sender = s
|
||||||
@ -449,11 +449,11 @@ func (gui *Gui) update() {
|
|||||||
object := state.GetAccount(gui.address())
|
object := state.GetAccount(gui.address())
|
||||||
|
|
||||||
if bytes.Compare(tx.Sender(), gui.address()) == 0 {
|
if bytes.Compare(tx.Sender(), gui.address()) == 0 {
|
||||||
object.SubAmount(tx.Value)
|
object.SubAmount(tx.Value())
|
||||||
|
|
||||||
gui.txDb.Put(tx.Hash(), tx.RlpEncode())
|
gui.txDb.Put(tx.Hash(), tx.RlpEncode())
|
||||||
} else if bytes.Compare(tx.Recipient, gui.address()) == 0 {
|
} else if bytes.Compare(tx.To(), gui.address()) == 0 {
|
||||||
object.AddAmount(tx.Value)
|
object.AddAmount(tx.Value())
|
||||||
|
|
||||||
gui.txDb.Put(tx.Hash(), tx.RlpEncode())
|
gui.txDb.Put(tx.Hash(), tx.RlpEncode())
|
||||||
}
|
}
|
||||||
|
@ -111,7 +111,7 @@ done:
|
|||||||
// If we are mining this block and validating we want to set the logs back to 0
|
// If we are mining this block and validating we want to set the logs back to 0
|
||||||
state.EmptyLogs()
|
state.EmptyLogs()
|
||||||
|
|
||||||
txGas := new(big.Int).Set(tx.Gas)
|
txGas := new(big.Int).Set(tx.Gas())
|
||||||
|
|
||||||
cb := state.GetStateObject(coinbase.Address())
|
cb := state.GetStateObject(coinbase.Address())
|
||||||
st := NewStateTransition(cb, tx, state, block)
|
st := NewStateTransition(cb, tx, state, block)
|
||||||
@ -134,7 +134,7 @@ done:
|
|||||||
}
|
}
|
||||||
|
|
||||||
txGas.Sub(txGas, st.gas)
|
txGas.Sub(txGas, st.gas)
|
||||||
cumulativeSum.Add(cumulativeSum, new(big.Int).Mul(txGas, tx.GasPrice))
|
cumulativeSum.Add(cumulativeSum, new(big.Int).Mul(txGas, tx.GasPrice()))
|
||||||
|
|
||||||
// Update the state with pending changes
|
// Update the state with pending changes
|
||||||
state.Update(txGas)
|
state.Update(txGas)
|
||||||
|
@ -5,6 +5,8 @@ import (
|
|||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
"github.com/ethereum/go-ethereum/ethutil"
|
||||||
"github.com/ethereum/go-ethereum/state"
|
"github.com/ethereum/go-ethereum/state"
|
||||||
"github.com/ethereum/go-ethereum/vm"
|
"github.com/ethereum/go-ethereum/vm"
|
||||||
)
|
)
|
||||||
@ -27,7 +29,7 @@ import (
|
|||||||
*/
|
*/
|
||||||
type StateTransition struct {
|
type StateTransition struct {
|
||||||
coinbase, receiver []byte
|
coinbase, receiver []byte
|
||||||
tx *types.Transaction
|
msg Message
|
||||||
gas, gasPrice *big.Int
|
gas, gasPrice *big.Int
|
||||||
value *big.Int
|
value *big.Int
|
||||||
data []byte
|
data []byte
|
||||||
@ -35,10 +37,42 @@ type StateTransition struct {
|
|||||||
block *types.Block
|
block *types.Block
|
||||||
|
|
||||||
cb, rec, sen *state.StateObject
|
cb, rec, sen *state.StateObject
|
||||||
|
|
||||||
|
Env vm.Environment
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewStateTransition(coinbase *state.StateObject, tx *types.Transaction, state *state.StateDB, block *types.Block) *StateTransition {
|
type Message interface {
|
||||||
return &StateTransition{coinbase.Address(), tx.Recipient, tx, new(big.Int), new(big.Int).Set(tx.GasPrice), tx.Value, tx.Data, state, block, coinbase, nil, nil}
|
Hash() []byte
|
||||||
|
|
||||||
|
CreatesContract() bool
|
||||||
|
|
||||||
|
From() []byte
|
||||||
|
To() []byte
|
||||||
|
|
||||||
|
GasValue() *big.Int
|
||||||
|
GasPrice() *big.Int
|
||||||
|
Gas() *big.Int
|
||||||
|
Value() *big.Int
|
||||||
|
|
||||||
|
Nonce() uint64
|
||||||
|
Data() []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func AddressFromMessage(msg Message) []byte {
|
||||||
|
// Generate a new address
|
||||||
|
return crypto.Sha3(ethutil.NewValue([]interface{}{msg.From(), msg.Nonce()}).Encode())[12:]
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewStateTransition(coinbase *state.StateObject, msg Message, state *state.StateDB, block *types.Block) *StateTransition {
|
||||||
|
return &StateTransition{coinbase.Address(), msg.To(), msg, new(big.Int), new(big.Int).Set(msg.GasPrice()), msg.Value(), msg.Data(), state, block, coinbase, nil, nil, nil}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *StateTransition) VmEnv() vm.Environment {
|
||||||
|
if self.Env == nil {
|
||||||
|
self.Env = NewEnv(self.state, self.msg, self.block)
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.Env
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *StateTransition) Coinbase() *state.StateObject {
|
func (self *StateTransition) Coinbase() *state.StateObject {
|
||||||
@ -49,17 +83,17 @@ func (self *StateTransition) Coinbase() *state.StateObject {
|
|||||||
self.cb = self.state.GetOrNewStateObject(self.coinbase)
|
self.cb = self.state.GetOrNewStateObject(self.coinbase)
|
||||||
return self.cb
|
return self.cb
|
||||||
}
|
}
|
||||||
func (self *StateTransition) Sender() *state.StateObject {
|
func (self *StateTransition) From() *state.StateObject {
|
||||||
if self.sen != nil {
|
if self.sen != nil {
|
||||||
return self.sen
|
return self.sen
|
||||||
}
|
}
|
||||||
|
|
||||||
self.sen = self.state.GetOrNewStateObject(self.tx.Sender())
|
self.sen = self.state.GetOrNewStateObject(self.msg.From())
|
||||||
|
|
||||||
return self.sen
|
return self.sen
|
||||||
}
|
}
|
||||||
func (self *StateTransition) Receiver() *state.StateObject {
|
func (self *StateTransition) To() *state.StateObject {
|
||||||
if self.tx != nil && self.tx.CreatesContract() {
|
if self.msg != nil && self.msg.CreatesContract() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,7 +101,7 @@ func (self *StateTransition) Receiver() *state.StateObject {
|
|||||||
return self.rec
|
return self.rec
|
||||||
}
|
}
|
||||||
|
|
||||||
self.rec = self.state.GetOrNewStateObject(self.tx.Recipient)
|
self.rec = self.state.GetOrNewStateObject(self.msg.To())
|
||||||
return self.rec
|
return self.rec
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,41 +121,41 @@ func (self *StateTransition) AddGas(amount *big.Int) {
|
|||||||
func (self *StateTransition) BuyGas() error {
|
func (self *StateTransition) BuyGas() error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
sender := self.Sender()
|
sender := self.From()
|
||||||
if sender.Balance().Cmp(self.tx.GasValue()) < 0 {
|
if sender.Balance().Cmp(self.msg.GasValue()) < 0 {
|
||||||
return fmt.Errorf("Insufficient funds to pre-pay gas. Req %v, has %v", self.tx.GasValue(), sender.Balance())
|
return fmt.Errorf("Insufficient funds to pre-pay gas. Req %v, has %v", self.msg.GasValue(), sender.Balance())
|
||||||
}
|
}
|
||||||
|
|
||||||
coinbase := self.Coinbase()
|
coinbase := self.Coinbase()
|
||||||
err = coinbase.BuyGas(self.tx.Gas, self.tx.GasPrice)
|
err = coinbase.BuyGas(self.msg.Gas(), self.msg.GasPrice())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
self.AddGas(self.tx.Gas)
|
self.AddGas(self.msg.Gas())
|
||||||
sender.SubAmount(self.tx.GasValue())
|
sender.SubAmount(self.msg.GasValue())
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *StateTransition) RefundGas() {
|
func (self *StateTransition) RefundGas() {
|
||||||
coinbase, sender := self.Coinbase(), self.Sender()
|
coinbase, sender := self.Coinbase(), self.From()
|
||||||
coinbase.RefundGas(self.gas, self.tx.GasPrice)
|
coinbase.RefundGas(self.gas, self.msg.GasPrice())
|
||||||
|
|
||||||
// Return remaining gas
|
// Return remaining gas
|
||||||
remaining := new(big.Int).Mul(self.gas, self.tx.GasPrice)
|
remaining := new(big.Int).Mul(self.gas, self.msg.GasPrice())
|
||||||
sender.AddAmount(remaining)
|
sender.AddAmount(remaining)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *StateTransition) preCheck() (err error) {
|
func (self *StateTransition) preCheck() (err error) {
|
||||||
var (
|
var (
|
||||||
tx = self.tx
|
msg = self.msg
|
||||||
sender = self.Sender()
|
sender = self.From()
|
||||||
)
|
)
|
||||||
|
|
||||||
// Make sure this transaction's nonce is correct
|
// Make sure this transaction's nonce is correct
|
||||||
if sender.Nonce != tx.Nonce {
|
if sender.Nonce != msg.Nonce() {
|
||||||
return NonceError(tx.Nonce, sender.Nonce)
|
return NonceError(msg.Nonce(), sender.Nonce)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pre-pay gas / Buy gas of the coinbase account
|
// Pre-pay gas / Buy gas of the coinbase account
|
||||||
@ -133,7 +167,7 @@ func (self *StateTransition) preCheck() (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *StateTransition) TransitionState() (err error) {
|
func (self *StateTransition) TransitionState() (err error) {
|
||||||
statelogger.Debugf("(~) %x\n", self.tx.Hash())
|
statelogger.Debugf("(~) %x\n", self.msg.Hash())
|
||||||
|
|
||||||
// XXX Transactions after this point are considered valid.
|
// XXX Transactions after this point are considered valid.
|
||||||
if err = self.preCheck(); err != nil {
|
if err = self.preCheck(); err != nil {
|
||||||
@ -141,8 +175,8 @@ func (self *StateTransition) TransitionState() (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
tx = self.tx
|
msg = self.msg
|
||||||
sender = self.Sender()
|
sender = self.From()
|
||||||
)
|
)
|
||||||
|
|
||||||
defer self.RefundGas()
|
defer self.RefundGas()
|
||||||
@ -169,15 +203,15 @@ func (self *StateTransition) TransitionState() (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var ret []byte
|
var ret []byte
|
||||||
vmenv := NewEnv(self.state, self.tx, self.block)
|
vmenv := self.VmEnv()
|
||||||
var ref vm.ClosureRef
|
var ref vm.ClosureRef
|
||||||
if tx.CreatesContract() {
|
if msg.CreatesContract() {
|
||||||
self.rec = MakeContract(tx, self.state)
|
self.rec = MakeContract(msg, self.state)
|
||||||
|
|
||||||
ret, err, ref = vmenv.Create(sender, self.rec.Address(), self.tx.Data, self.gas, self.gasPrice, self.value)
|
ret, err, ref = vmenv.Create(sender, self.rec.Address(), self.msg.Data(), self.gas, self.gasPrice, self.value)
|
||||||
ref.SetCode(ret)
|
ref.SetCode(ret)
|
||||||
} else {
|
} else {
|
||||||
ret, err = vmenv.Call(self.Sender(), self.Receiver().Address(), self.tx.Data, self.gas, self.gasPrice, self.value)
|
ret, err = vmenv.Call(self.From(), self.To().Address(), self.msg.Data(), self.gas, self.gasPrice, self.value)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
statelogger.Debugln(err)
|
statelogger.Debugln(err)
|
||||||
@ -187,11 +221,11 @@ func (self *StateTransition) TransitionState() (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Converts an transaction in to a state object
|
// Converts an transaction in to a state object
|
||||||
func MakeContract(tx *types.Transaction, state *state.StateDB) *state.StateObject {
|
func MakeContract(msg Message, state *state.StateDB) *state.StateObject {
|
||||||
addr := tx.CreationAddress(state)
|
addr := AddressFromMessage(msg)
|
||||||
|
|
||||||
contract := state.GetOrNewStateObject(addr)
|
contract := state.GetOrNewStateObject(addr)
|
||||||
contract.InitCode = tx.Data
|
contract.InitCode = msg.Data()
|
||||||
|
|
||||||
return contract
|
return contract
|
||||||
}
|
}
|
||||||
|
@ -112,8 +112,8 @@ func (pool *TxPool) ValidateTransaction(tx *types.Transaction) error {
|
|||||||
return fmt.Errorf("No last block on the block chain")
|
return fmt.Errorf("No last block on the block chain")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(tx.Recipient) != 0 && len(tx.Recipient) != 20 {
|
if len(tx.To()) != 0 && len(tx.To()) != 20 {
|
||||||
return fmt.Errorf("Invalid recipient. len = %d", len(tx.Recipient))
|
return fmt.Errorf("Invalid recipient. len = %d", len(tx.To()))
|
||||||
}
|
}
|
||||||
|
|
||||||
v, _, _ := tx.Curve()
|
v, _, _ := tx.Curve()
|
||||||
@ -124,15 +124,15 @@ func (pool *TxPool) ValidateTransaction(tx *types.Transaction) error {
|
|||||||
// Get the sender
|
// Get the sender
|
||||||
sender := pool.chainManager.State().GetAccount(tx.Sender())
|
sender := pool.chainManager.State().GetAccount(tx.Sender())
|
||||||
|
|
||||||
totAmount := new(big.Int).Set(tx.Value)
|
totAmount := new(big.Int).Set(tx.Value())
|
||||||
// Make sure there's enough in the sender's account. Having insufficient
|
// Make sure there's enough in the sender's account. Having insufficient
|
||||||
// funds won't invalidate this transaction but simple ignores it.
|
// funds won't invalidate this transaction but simple ignores it.
|
||||||
if sender.Balance().Cmp(totAmount) < 0 {
|
if sender.Balance().Cmp(totAmount) < 0 {
|
||||||
return fmt.Errorf("Insufficient amount in sender's (%x) account", tx.Sender())
|
return fmt.Errorf("Insufficient amount in sender's (%x) account", tx.From())
|
||||||
}
|
}
|
||||||
|
|
||||||
if tx.IsContract() {
|
if tx.IsContract() {
|
||||||
if tx.GasPrice.Cmp(big.NewInt(minGasPrice)) < 0 {
|
if tx.GasPrice().Cmp(big.NewInt(minGasPrice)) < 0 {
|
||||||
return fmt.Errorf("Gasprice too low, %s given should be at least %d.", tx.GasPrice, minGasPrice)
|
return fmt.Errorf("Gasprice too low, %s given should be at least %d.", tx.GasPrice, minGasPrice)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -160,10 +160,7 @@ func (self *TxPool) Add(tx *types.Transaction) error {
|
|||||||
|
|
||||||
self.addTransaction(tx)
|
self.addTransaction(tx)
|
||||||
|
|
||||||
tmp := make([]byte, 4)
|
txplogger.Debugf("(t) %x => %x (%v) %x\n", tx.From()[:4], tx.To()[:4], tx.Value, tx.Hash())
|
||||||
copy(tmp, tx.Recipient)
|
|
||||||
|
|
||||||
txplogger.Debugf("(t) %x => %x (%v) %x\n", tx.Sender()[:4], tmp, tx.Value, tx.Hash())
|
|
||||||
|
|
||||||
// Notify the subscribers
|
// Notify the subscribers
|
||||||
go self.eventMux.Post(TxPreEvent{tx})
|
go self.eventMux.Post(TxPreEvent{tx})
|
||||||
@ -200,7 +197,7 @@ func (pool *TxPool) RemoveInvalid(state *state.StateDB) {
|
|||||||
tx := e.Value.(*types.Transaction)
|
tx := e.Value.(*types.Transaction)
|
||||||
sender := state.GetAccount(tx.Sender())
|
sender := state.GetAccount(tx.Sender())
|
||||||
err := pool.ValidateTransaction(tx)
|
err := pool.ValidateTransaction(tx)
|
||||||
if err != nil || sender.Nonce >= tx.Nonce {
|
if err != nil || sender.Nonce >= tx.Nonce() {
|
||||||
pool.pool.Remove(e)
|
pool.pool.Remove(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ import (
|
|||||||
|
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/ethutil"
|
"github.com/ethereum/go-ethereum/ethutil"
|
||||||
"github.com/ethereum/go-ethereum/state"
|
|
||||||
"github.com/obscuren/secp256k1-go"
|
"github.com/obscuren/secp256k1-go"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -18,12 +17,12 @@ func IsContractAddr(addr []byte) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Transaction struct {
|
type Transaction struct {
|
||||||
Nonce uint64
|
nonce uint64
|
||||||
Recipient []byte
|
recipient []byte
|
||||||
Value *big.Int
|
value *big.Int
|
||||||
Gas *big.Int
|
gas *big.Int
|
||||||
GasPrice *big.Int
|
gasPrice *big.Int
|
||||||
Data []byte
|
data []byte
|
||||||
v byte
|
v byte
|
||||||
r, s []byte
|
r, s []byte
|
||||||
|
|
||||||
@ -32,11 +31,11 @@ type Transaction struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewContractCreationTx(value, gas, gasPrice *big.Int, script []byte) *Transaction {
|
func NewContractCreationTx(value, gas, gasPrice *big.Int, script []byte) *Transaction {
|
||||||
return &Transaction{Recipient: nil, Value: value, Gas: gas, GasPrice: gasPrice, Data: script, contractCreation: true}
|
return &Transaction{recipient: nil, value: value, gas: gas, gasPrice: gasPrice, data: script, contractCreation: true}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTransactionMessage(to []byte, value, gas, gasPrice *big.Int, data []byte) *Transaction {
|
func NewTransactionMessage(to []byte, value, gas, gasPrice *big.Int, data []byte) *Transaction {
|
||||||
return &Transaction{Recipient: to, Value: value, GasPrice: gasPrice, Gas: gas, Data: data, contractCreation: IsContractAddr(to)}
|
return &Transaction{recipient: to, value: value, gasPrice: gasPrice, gas: gas, data: data, contractCreation: IsContractAddr(to)}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTransactionFromBytes(data []byte) *Transaction {
|
func NewTransactionFromBytes(data []byte) *Transaction {
|
||||||
@ -54,20 +53,52 @@ func NewTransactionFromValue(val *ethutil.Value) *Transaction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *Transaction) GasValue() *big.Int {
|
func (self *Transaction) GasValue() *big.Int {
|
||||||
return new(big.Int).Mul(self.Gas, self.GasPrice)
|
return new(big.Int).Mul(self.gas, self.gasPrice)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Transaction) TotalValue() *big.Int {
|
func (self *Transaction) TotalValue() *big.Int {
|
||||||
v := self.GasValue()
|
v := self.GasValue()
|
||||||
return v.Add(v, self.Value)
|
return v.Add(v, self.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tx *Transaction) Hash() []byte {
|
func (tx *Transaction) Hash() []byte {
|
||||||
data := []interface{}{tx.Nonce, tx.GasPrice, tx.Gas, tx.Recipient, tx.Value, tx.Data}
|
data := []interface{}{tx.Nonce, tx.gasPrice, tx.gas, tx.recipient, tx.Value, tx.Data}
|
||||||
|
|
||||||
return crypto.Sha3(ethutil.NewValue(data).Encode())
|
return crypto.Sha3(ethutil.NewValue(data).Encode())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *Transaction) Data() []byte {
|
||||||
|
return self.data
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Transaction) Gas() *big.Int {
|
||||||
|
return self.gas
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Transaction) GasPrice() *big.Int {
|
||||||
|
return self.gasPrice
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Transaction) Value() *big.Int {
|
||||||
|
return self.value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Transaction) Nonce() uint64 {
|
||||||
|
return self.nonce
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Transaction) SetNonce(nonce uint64) {
|
||||||
|
self.nonce = nonce
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Transaction) From() []byte {
|
||||||
|
return self.Sender()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Transaction) To() []byte {
|
||||||
|
return self.recipient
|
||||||
|
}
|
||||||
|
|
||||||
func (tx *Transaction) CreatesContract() bool {
|
func (tx *Transaction) CreatesContract() bool {
|
||||||
return tx.contractCreation
|
return tx.contractCreation
|
||||||
}
|
}
|
||||||
@ -77,11 +108,6 @@ func (tx *Transaction) IsContract() bool {
|
|||||||
return tx.CreatesContract()
|
return tx.CreatesContract()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tx *Transaction) CreationAddress(state *state.StateDB) []byte {
|
|
||||||
// Generate a new address
|
|
||||||
return crypto.Sha3(ethutil.NewValue([]interface{}{tx.Sender(), tx.Nonce}).Encode())[12:]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tx *Transaction) Curve() (v byte, r []byte, s []byte) {
|
func (tx *Transaction) Curve() (v byte, r []byte, s []byte) {
|
||||||
v = tx.v
|
v = tx.v
|
||||||
r = ethutil.LeftPadBytes(tx.r, 32)
|
r = ethutil.LeftPadBytes(tx.r, 32)
|
||||||
@ -136,7 +162,7 @@ func (tx *Transaction) Sign(privk []byte) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (tx *Transaction) RlpData() interface{} {
|
func (tx *Transaction) RlpData() interface{} {
|
||||||
data := []interface{}{tx.Nonce, tx.GasPrice, tx.Gas, tx.Recipient, tx.Value, tx.Data}
|
data := []interface{}{tx.Nonce, tx.GasPrice, tx.Gas, tx.recipient, tx.Value, tx.Data}
|
||||||
|
|
||||||
// TODO Remove prefixing zero's
|
// TODO Remove prefixing zero's
|
||||||
|
|
||||||
@ -156,18 +182,18 @@ func (tx *Transaction) RlpDecode(data []byte) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (tx *Transaction) RlpValueDecode(decoder *ethutil.Value) {
|
func (tx *Transaction) RlpValueDecode(decoder *ethutil.Value) {
|
||||||
tx.Nonce = decoder.Get(0).Uint()
|
tx.nonce = decoder.Get(0).Uint()
|
||||||
tx.GasPrice = decoder.Get(1).BigInt()
|
tx.gasPrice = decoder.Get(1).BigInt()
|
||||||
tx.Gas = decoder.Get(2).BigInt()
|
tx.gas = decoder.Get(2).BigInt()
|
||||||
tx.Recipient = decoder.Get(3).Bytes()
|
tx.recipient = decoder.Get(3).Bytes()
|
||||||
tx.Value = decoder.Get(4).BigInt()
|
tx.value = decoder.Get(4).BigInt()
|
||||||
tx.Data = decoder.Get(5).Bytes()
|
tx.data = decoder.Get(5).Bytes()
|
||||||
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 IsContractAddr(tx.Recipient) {
|
if IsContractAddr(tx.recipient) {
|
||||||
tx.contractCreation = true
|
tx.contractCreation = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -188,12 +214,12 @@ func (tx *Transaction) String() string {
|
|||||||
S: 0x%x
|
S: 0x%x
|
||||||
`,
|
`,
|
||||||
tx.Hash(),
|
tx.Hash(),
|
||||||
len(tx.Recipient) == 0,
|
len(tx.recipient) == 0,
|
||||||
tx.Sender(),
|
tx.Sender(),
|
||||||
tx.Recipient,
|
tx.recipient,
|
||||||
tx.Nonce,
|
tx.nonce,
|
||||||
tx.GasPrice,
|
tx.gasPrice,
|
||||||
tx.Gas,
|
tx.gas,
|
||||||
tx.Value,
|
tx.Value,
|
||||||
tx.Data,
|
tx.Data,
|
||||||
tx.v,
|
tx.v,
|
||||||
@ -221,5 +247,5 @@ func (s Transactions) GetRlp(i int) []byte { return ethutil.Rlp(s[i]) }
|
|||||||
type TxByNonce struct{ Transactions }
|
type TxByNonce struct{ Transactions }
|
||||||
|
|
||||||
func (s TxByNonce) Less(i, j int) bool {
|
func (s TxByNonce) Less(i, j int) bool {
|
||||||
return s.Transactions[i].Nonce < s.Transactions[j].Nonce
|
return s.Transactions[i].nonce < s.Transactions[j].nonce
|
||||||
}
|
}
|
||||||
|
@ -11,26 +11,26 @@ import (
|
|||||||
type VMEnv struct {
|
type VMEnv struct {
|
||||||
state *state.StateDB
|
state *state.StateDB
|
||||||
block *types.Block
|
block *types.Block
|
||||||
tx *types.Transaction
|
msg Message
|
||||||
depth int
|
depth int
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewEnv(state *state.StateDB, tx *types.Transaction, block *types.Block) *VMEnv {
|
func NewEnv(state *state.StateDB, msg Message, block *types.Block) *VMEnv {
|
||||||
return &VMEnv{
|
return &VMEnv{
|
||||||
state: state,
|
state: state,
|
||||||
block: block,
|
block: block,
|
||||||
tx: tx,
|
msg: msg,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *VMEnv) Origin() []byte { return self.tx.Sender() }
|
func (self *VMEnv) Origin() []byte { return self.msg.From() }
|
||||||
func (self *VMEnv) BlockNumber() *big.Int { return self.block.Number }
|
func (self *VMEnv) BlockNumber() *big.Int { return self.block.Number }
|
||||||
func (self *VMEnv) PrevHash() []byte { return self.block.PrevHash }
|
func (self *VMEnv) PrevHash() []byte { return self.block.PrevHash }
|
||||||
func (self *VMEnv) Coinbase() []byte { return self.block.Coinbase }
|
func (self *VMEnv) Coinbase() []byte { return self.block.Coinbase }
|
||||||
func (self *VMEnv) Time() int64 { return self.block.Time }
|
func (self *VMEnv) Time() int64 { return self.block.Time }
|
||||||
func (self *VMEnv) Difficulty() *big.Int { return self.block.Difficulty }
|
func (self *VMEnv) Difficulty() *big.Int { return self.block.Difficulty }
|
||||||
func (self *VMEnv) BlockHash() []byte { return self.block.Hash() }
|
func (self *VMEnv) BlockHash() []byte { return self.block.Hash() }
|
||||||
func (self *VMEnv) Value() *big.Int { return self.tx.Value }
|
func (self *VMEnv) Value() *big.Int { return self.msg.Value() }
|
||||||
func (self *VMEnv) State() *state.StateDB { return self.state }
|
func (self *VMEnv) State() *state.StateDB { return self.state }
|
||||||
func (self *VMEnv) GasLimit() *big.Int { return self.block.GasLimit }
|
func (self *VMEnv) GasLimit() *big.Int { return self.block.GasLimit }
|
||||||
func (self *VMEnv) Depth() int { return self.depth }
|
func (self *VMEnv) Depth() int { return self.depth }
|
||||||
|
@ -237,8 +237,8 @@ func (self *Miner) finiliseTxs() types.Transactions {
|
|||||||
key := self.eth.KeyManager()
|
key := self.eth.KeyManager()
|
||||||
for i, ltx := range self.localTxs {
|
for i, ltx := range self.localTxs {
|
||||||
tx := types.NewTransactionMessage(ltx.To, ethutil.Big(ltx.Value), ethutil.Big(ltx.Gas), ethutil.Big(ltx.GasPrice), ltx.Data)
|
tx := types.NewTransactionMessage(ltx.To, ethutil.Big(ltx.Value), ethutil.Big(ltx.Gas), ethutil.Big(ltx.GasPrice), ltx.Data)
|
||||||
tx.Nonce = state.GetNonce(self.Coinbase)
|
tx.SetNonce(state.GetNonce(self.Coinbase))
|
||||||
state.SetNonce(self.Coinbase, tx.Nonce+1)
|
state.SetNonce(self.Coinbase, tx.Nonce()+1)
|
||||||
|
|
||||||
tx.Sign(key.PrivateKey())
|
tx.Sign(key.PrivateKey())
|
||||||
|
|
||||||
@ -247,7 +247,7 @@ func (self *Miner) finiliseTxs() types.Transactions {
|
|||||||
|
|
||||||
// Faster than append
|
// Faster than append
|
||||||
for _, tx := range self.eth.TxPool().CurrentTransactions() {
|
for _, tx := range self.eth.TxPool().CurrentTransactions() {
|
||||||
if tx.GasPrice.Cmp(self.MinAcceptedGasPrice) >= 0 {
|
if tx.GasPrice().Cmp(self.MinAcceptedGasPrice) >= 0 {
|
||||||
txs[actualSize] = tx
|
txs[actualSize] = tx
|
||||||
actualSize++
|
actualSize++
|
||||||
}
|
}
|
||||||
|
@ -216,7 +216,7 @@ func (self *JSXEth) Transact(key, toStr, valueStr, gasStr, gasPriceStr, codeStr
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
if types.IsContractAddr(to) {
|
if types.IsContractAddr(to) {
|
||||||
return ethutil.Bytes2Hex(tx.CreationAddress(nil)), nil
|
return ethutil.Bytes2Hex(core.AddressFromMessage(tx)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return ethutil.Bytes2Hex(tx.Hash()), nil
|
return ethutil.Bytes2Hex(tx.Hash()), nil
|
||||||
@ -229,7 +229,7 @@ func (self *JSXEth) PushTx(txStr string) (*JSReceipt, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return NewJSReciept(tx.CreatesContract(), tx.CreationAddress(self.World().State()), tx.Hash(), tx.Sender()), nil
|
return NewJSReciept(tx.CreatesContract(), core.AddressFromMessage(tx), tx.Hash(), tx.From()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *JSXEth) CompileMutan(code string) string {
|
func (self *JSXEth) CompileMutan(code string) string {
|
||||||
|
@ -97,21 +97,21 @@ type JSTransaction struct {
|
|||||||
|
|
||||||
func NewJSTx(tx *types.Transaction, state *state.StateDB) *JSTransaction {
|
func NewJSTx(tx *types.Transaction, state *state.StateDB) *JSTransaction {
|
||||||
hash := ethutil.Bytes2Hex(tx.Hash())
|
hash := ethutil.Bytes2Hex(tx.Hash())
|
||||||
receiver := ethutil.Bytes2Hex(tx.Recipient)
|
receiver := ethutil.Bytes2Hex(tx.To())
|
||||||
if receiver == "0000000000000000000000000000000000000000" {
|
if receiver == "0000000000000000000000000000000000000000" {
|
||||||
receiver = ethutil.Bytes2Hex(tx.CreationAddress(state))
|
receiver = ethutil.Bytes2Hex(core.AddressFromMessage(tx))
|
||||||
}
|
}
|
||||||
sender := ethutil.Bytes2Hex(tx.Sender())
|
sender := ethutil.Bytes2Hex(tx.Sender())
|
||||||
createsContract := tx.CreatesContract()
|
createsContract := tx.CreatesContract()
|
||||||
|
|
||||||
var data string
|
var data string
|
||||||
if tx.CreatesContract() {
|
if tx.CreatesContract() {
|
||||||
data = strings.Join(core.Disassemble(tx.Data), "\n")
|
data = strings.Join(core.Disassemble(tx.Data()), "\n")
|
||||||
} else {
|
} else {
|
||||||
data = ethutil.Bytes2Hex(tx.Data)
|
data = ethutil.Bytes2Hex(tx.Data())
|
||||||
}
|
}
|
||||||
|
|
||||||
return &JSTransaction{ref: tx, Hash: hash, Value: ethutil.CurrencyToString(tx.Value), Address: receiver, Contract: tx.CreatesContract(), Gas: tx.Gas.String(), GasPrice: tx.GasPrice.String(), Data: data, Sender: sender, CreatesContract: createsContract, RawData: ethutil.Bytes2Hex(tx.Data)}
|
return &JSTransaction{ref: tx, Hash: hash, Value: ethutil.CurrencyToString(tx.Value()), Address: receiver, Contract: tx.CreatesContract(), Gas: tx.Gas().String(), GasPrice: tx.GasPrice().String(), Data: data, Sender: sender, CreatesContract: createsContract, RawData: ethutil.Bytes2Hex(tx.Data())}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *JSTransaction) ToString() string {
|
func (self *JSTransaction) ToString() string {
|
||||||
|
@ -134,7 +134,7 @@ func (self *XEth) Transact(key *crypto.KeyPair, to []byte, value, gas, price *et
|
|||||||
state := self.chainManager.TransState()
|
state := self.chainManager.TransState()
|
||||||
nonce := state.GetNonce(key.Address())
|
nonce := state.GetNonce(key.Address())
|
||||||
|
|
||||||
tx.Nonce = nonce
|
tx.SetNonce(nonce)
|
||||||
tx.Sign(key.PrivateKey)
|
tx.Sign(key.PrivateKey)
|
||||||
|
|
||||||
// Do some pre processing for our "pre" events and hooks
|
// Do some pre processing for our "pre" events and hooks
|
||||||
@ -150,7 +150,7 @@ func (self *XEth) Transact(key *crypto.KeyPair, to []byte, value, gas, price *et
|
|||||||
state.SetNonce(key.Address(), nonce+1)
|
state.SetNonce(key.Address(), nonce+1)
|
||||||
|
|
||||||
if contractCreation {
|
if contractCreation {
|
||||||
addr := tx.CreationAddress(self.World().State())
|
addr := core.AddressFromMessage(tx)
|
||||||
pipelogger.Infof("Contract addr %x\n", addr)
|
pipelogger.Infof("Contract addr %x\n", addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,8 +163,8 @@ func (self *XEth) PushTx(tx *types.Transaction) ([]byte, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if tx.Recipient == nil {
|
if tx.To() == nil {
|
||||||
addr := tx.CreationAddress(self.World().State())
|
addr := core.AddressFromMessage(tx)
|
||||||
pipelogger.Infof("Contract addr %x\n", addr)
|
pipelogger.Infof("Contract addr %x\n", addr)
|
||||||
return addr, nil
|
return addr, nil
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user