@@ -5,6 +5,7 @@ const BN = ethUtil.BN
55const exceptions = require ( './exceptions.js' )
66
77const ERROR = exceptions . ERROR
8+ const EMPTY_CODE_HASH = ethUtil . keccak256 ( )
89
910/**
1011 * runs a CALL operation
@@ -47,6 +48,7 @@ module.exports = function (opts, cb) {
4748 var selfdestruct = opts . selfdestruct || opts . suicides
4849 var delegatecall = opts . delegatecall || false
4950 var isStatic = opts . static || false
51+ var salt = opts . salt || null
5052
5153 txValue = new BN ( txValue )
5254
@@ -77,41 +79,14 @@ module.exports = function (opts, cb) {
7779 code = txData
7880 txData = undefined
7981 var newNonce = new BN ( account . nonce ) . subn ( 1 )
80- createdAddress = toAddress = ethUtil . generateAddress ( caller , newNonce . toArray ( ) )
81- stateManager . clearContractStorage ( createdAddress , function ( err ) {
82- if ( err ) {
83- done ( err )
84- }
8582
86- async . series ( [
87- newContractEvent ,
88- getAccount
89- ] , done )
90-
91- function newContractEvent ( callback ) {
92- /**
93- * The `newContract` event when a contract is created
94- *
95- * @event Event: newContract
96- * @type {Object }
97- * @property {Buffer } address the created address for the new contract (type `Buffer | Uint8Array`)
98- * @property {Buffer } code the deployment bytecode for reference (type `Buffer | Uint8Array`)
99- */
100- self . emit ( 'newContract' , {
101- address : createdAddress ,
102- code : code
103- } , callback )
104- }
83+ if ( salt ) {
84+ createdAddress = toAddress = ethUtil . generateAddress2 ( caller , salt , code )
85+ } else {
86+ createdAddress = toAddress = ethUtil . generateAddress ( caller , newNonce . toArray ( ) )
87+ }
10588
106- function getAccount ( callback ) {
107- stateManager . getAccount ( createdAddress , function ( err , account ) {
108- toAccount = account
109- const NONCE_OFFSET = 1
110- toAccount . nonce = new BN ( toAccount . nonce ) . addn ( NONCE_OFFSET ) . toArrayLike ( Buffer )
111- callback ( err )
112- } )
113- }
114- } )
89+ checkAccountState ( createdAddress , setupNewContract , done )
11590 } else {
11691 // else load the `to` account
11792 stateManager . getAccount ( toAddress , function ( err , account ) {
@@ -121,6 +96,53 @@ module.exports = function (opts, cb) {
12196 }
12297 }
12398
99+ function checkAccountState ( address , next , done ) {
100+ stateManager . getAccount ( address , function ( err , account ) {
101+ if ( err ) {
102+ done ( err )
103+ return
104+ }
105+
106+ if ( ( account . nonce && new BN ( account . nonce ) > 0 ) || account . codeHash . compare ( EMPTY_CODE_HASH ) !== 0 ) {
107+ toAccount = account
108+ code = new Buffer ( '0xfe' , 'hex' ) // Invalid init code
109+ done ( )
110+ return
111+ }
112+
113+ next ( address , done )
114+ } )
115+ }
116+
117+ function setupNewContract ( address , done ) {
118+ stateManager . clearContractStorage ( address , function ( err ) {
119+ if ( err ) {
120+ done ( err )
121+ return
122+ }
123+
124+ async . series ( [
125+ newContractEvent ,
126+ getAccount
127+ ] , done )
128+
129+ function newContractEvent ( callback ) {
130+ self . emit ( 'newContract' , {
131+ address : address ,
132+ code : code
133+ } , callback )
134+ }
135+
136+ function getAccount ( callback ) {
137+ stateManager . getAccount ( address , function ( err , account ) {
138+ toAccount = account
139+ toAccount . nonce = new BN ( toAccount . nonce ) . addn ( 1 ) . toArrayLike ( Buffer )
140+ callback ( err )
141+ } )
142+ }
143+ } )
144+ }
145+
124146 function subTxValue ( cb ) {
125147 if ( delegatecall ) {
126148 cb ( )
0 commit comments