Changed CREATE

poc8
obscuren 11 years ago
parent 6748158ab4
commit 40e3d2ab55
  1. 59
      ethchain/vm.go

@ -617,48 +617,59 @@ func (vm *Vm) RunClosure(closure *Closure) (ret []byte, err error) {
case CREATE:
require(3)
value := stack.Pop()
size, offset := stack.Popn()
var (
err error
value = stack.Pop()
size, offset = stack.Popn()
// Snapshot the current stack so we are able to
// revert back to it later.
snapshot := vm.state.Copy()
// Snapshot the current stack so we are able to
// revert back to it later.
snapshot = vm.state.Copy()
)
// Generate a new address
addr := ethcrypto.CreateAddress(closure.caller.Address(), closure.caller.N())
for i := int64(0); vm.state.GetStateObject(addr) != nil; i++ {
t := new(big.Int).Set(closure.caller.N())
addr = ethcrypto.CreateAddress(closure.caller.Address(), t.Add(t, big.NewInt(i)))
}
vm.Printf(" (*) %x", addr).Endl()
// Create a new contract
contract := vm.state.NewStateObject(addr)
contract.Amount = value
// Set the init script
contract.initScript = ethutil.BigD(mem.Get(offset.Int64(), size.Int64())).Bytes()
// Transfer all remaining gas to the new
// contract so it may run the init script
gas := new(big.Int).Set(closure.Gas)
// Create the closure
c := NewClosure(closure.caller,
closure.Object(),
contract.initScript,
vm.state,
gas,
closure.Price)
// Call the closure and set the return value as
// main script.
var err error
c.Script, gas, err = c.Call(vm, nil)
if contract.Amount.Cmp(value) >= 0 {
closure.object.SubAmount(value)
contract.AddAmount(value)
// Set the init script
contract.initScript = ethutil.BigD(mem.Get(offset.Int64(), size.Int64())).Bytes()
// Transfer all remaining gas to the new
// contract so it may run the init script
gas := new(big.Int).Set(closure.Gas)
closure.UseGas(closure.Gas)
// Create the closure
c := NewClosure(closure, contract, contract.initScript, vm.state, gas, closure.Price)
// Call the closure and set the return value as
// main script.
c.Script, err, _ = Call(vm, c, nil)
} else {
err = fmt.Errorf("Insufficient funds to transfer value. Req %v, has %v", value, closure.object.Amount)
}
if err != nil {
stack.Push(ethutil.BigFalse)
// Revert the state as it was before.
vm.state.Set(snapshot)
vm.Printf("CREATE err %v", err)
} else {
stack.Push(ethutil.BigD(addr))
vm.Printf("CREATE success")
}
vm.Endl()
case CALL:
require(7)

Loading…
Cancel
Save