@@ -47,6 +47,7 @@ module.exports = function (opts, cb) {
47
47
var selfdestruct = opts . selfdestruct || opts . suicides
48
48
var delegatecall = opts . delegatecall || false
49
49
var isStatic = opts . static || false
50
+ var salt = opts . salt || null
50
51
51
52
txValue = new BN ( txValue )
52
53
@@ -77,41 +78,14 @@ module.exports = function (opts, cb) {
77
78
code = txData
78
79
txData = undefined
79
80
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 )
90
81
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
+ }
105
87
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 )
115
89
} else {
116
90
// else load the `to` account
117
91
stateManager . getAccount ( toAddress , function ( err , account ) {
@@ -121,6 +95,53 @@ module.exports = function (opts, cb) {
121
95
}
122
96
}
123
97
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
+
124
145
function subTxValue ( cb ) {
125
146
if ( delegatecall ) {
126
147
cb ( )
@@ -199,7 +220,6 @@ module.exports = function (opts, cb) {
199
220
var totalGas = results . gasUsed
200
221
if ( ! results . runState . vmError ) {
201
222
var returnFee = new BN ( results . return . length * self . _common . param ( 'gasPrices' , 'createData' ) )
202
-
203
223
totalGas = totalGas . add ( returnFee )
204
224
}
205
225
// if not enough gas
0 commit comments