@@ -47,6 +47,7 @@ module.exports = function (opts, cb) {
4747 var selfdestruct = opts . selfdestruct || opts . suicides
4848 var delegatecall = opts . delegatecall || false
4949 var isStatic = opts . static || false
50+ var salt = opts . salt || null
5051
5152 txValue = new BN ( txValue )
5253
@@ -77,41 +78,14 @@ module.exports = function (opts, cb) {
7778 code = txData
7879 txData = undefined
7980 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- }
85-
86- async . series ( [
87- newContractEvent ,
88- getAccount
89- ] , done )
9081
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- }
82+ if ( salt ) {
83+ createdAddress = toAddress = ethUtil . generateAddress2 ( caller , salt , code )
84+ } else {
85+ createdAddress = toAddress = ethUtil . generateAddress ( caller , newNonce . toArray ( ) )
86+ }
10587
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- } )
88+ checkAccountState ( createdAddress , setupNewContract , done )
11589 } else {
11690 // else load the `to` account
11791 stateManager . getAccount ( toAddress , function ( err , account ) {
@@ -121,6 +95,53 @@ module.exports = function (opts, cb) {
12195 }
12296 }
12397
98+ function checkAccountState ( address , next , done ) {
99+ stateManager . getAccount ( address , function ( err , account ) {
100+ if ( err ) {
101+ done ( err )
102+ return
103+ }
104+
105+ if ( ( account . nonce && new BN ( account . nonce ) > 0 ) || account . codeHash . compare ( ethUtil . KECCAK256_NULL ) !== 0 ) {
106+ toAccount = account
107+ code = new Buffer ( 'fe' , 'hex' ) // Invalid init code
108+ done ( )
109+ return
110+ }
111+
112+ next ( address , done )
113+ } )
114+ }
115+
116+ function setupNewContract ( address , done ) {
117+ stateManager . clearContractStorage ( address , function ( err ) {
118+ if ( err ) {
119+ done ( err )
120+ return
121+ }
122+
123+ async . series ( [
124+ newContractEvent ,
125+ getAccount
126+ ] , done )
127+
128+ function newContractEvent ( callback ) {
129+ self . emit ( 'newContract' , {
130+ address : address ,
131+ code : code
132+ } , callback )
133+ }
134+
135+ function getAccount ( callback ) {
136+ stateManager . getAccount ( address , function ( err , account ) {
137+ toAccount = account
138+ toAccount . nonce = new BN ( toAccount . nonce ) . addn ( 1 ) . toArrayLike ( Buffer )
139+ callback ( err )
140+ } )
141+ }
142+ } )
143+ }
144+
124145 function subTxValue ( cb ) {
125146 if ( delegatecall ) {
126147 cb ( )
@@ -199,7 +220,6 @@ module.exports = function (opts, cb) {
199220 var totalGas = results . gasUsed
200221 if ( ! results . runState . vmError ) {
201222 var returnFee = new BN ( results . return . length * self . _common . param ( 'gasPrices' , 'createData' ) )
202-
203223 totalGas = totalGas . add ( returnFee )
204224 }
205225 // if not enough gas
0 commit comments