Changed CREATE

pull/150/head
obscuren 10 years ago
parent 6748158ab4
commit 40e3d2ab55
  1. 35
      ethchain/vm.go

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

Loading…
Cancel
Save