Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
B
baas-ide
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
JIRA
JIRA
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
guxukai
baas-ide
Commits
51d58133
Unverified
Commit
51d58133
authored
Feb 12, 2018
by
yann300
Committed by
GitHub
Feb 12, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #684 from ethereum/refactor/move_tx_to_remix_lib
move most tx code from browser-solidity
parents
414cf23b
328913af
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
797 additions
and
1 deletion
+797
-1
index.js
remix-lib/index.js
+15
-0
package.json
remix-lib/package.json
+5
-1
eventsDecoder.js
remix-lib/src/execution/eventsDecoder.js
+123
-0
execution-context.js
remix-lib/src/execution/execution-context.js
+227
-0
txExecution.js
remix-lib/src/execution/txExecution.js
+76
-0
txFormat.js
remix-lib/src/execution/txFormat.js
+229
-0
txHelper.js
remix-lib/src/execution/txHelper.js
+122
-0
txListener.js
remix-lib/src/execution/txListener.js
+0
-0
No files found.
remix-lib/index.js
View file @
51d58133
...
@@ -17,6 +17,13 @@ var styleGuideDark = require('./src/ui/styleGuideDark')
...
@@ -17,6 +17,13 @@ var styleGuideDark = require('./src/ui/styleGuideDark')
var
themeChooser
=
require
(
'./src/ui/theme-chooser'
)
var
themeChooser
=
require
(
'./src/ui/theme-chooser'
)
var
Storage
=
require
(
'./src/storage'
)
var
Storage
=
require
(
'./src/storage'
)
var
EventsDecoder
=
require
(
'./src/execution/eventsDecoder'
)
var
txExecution
=
require
(
'./src/execution/txExecution'
)
var
txHelper
=
require
(
'./src/execution/txHelper'
)
var
txFormat
=
require
(
'./src/execution/txFormat'
)
var
txListener
=
require
(
'./src/execution/txListener'
)
var
executionContext
=
require
(
'./src/execution/execution-context'
)
if
(
typeof
(
module
)
!==
'undefined'
&&
typeof
(
module
.
exports
)
!==
'undefined'
)
{
if
(
typeof
(
module
)
!==
'undefined'
&&
typeof
(
module
.
exports
)
!==
'undefined'
)
{
module
.
exports
=
modules
()
module
.
exports
=
modules
()
}
}
...
@@ -49,6 +56,14 @@ function modules () {
...
@@ -49,6 +56,14 @@ function modules () {
styleGuide
:
styleGuide
,
styleGuide
:
styleGuide
,
styleGuideDark
:
styleGuideDark
,
styleGuideDark
:
styleGuideDark
,
themeChooser
:
themeChooser
themeChooser
:
themeChooser
},
execution
:
{
EventsDecoder
:
EventsDecoder
,
txExecution
:
txExecution
,
txHelper
:
txHelper
,
executionContext
:
executionContext
,
txFormat
:
txFormat
,
txListener
:
txListener
}
}
}
}
}
}
remix-lib/package.json
View file @
51d58133
...
@@ -17,9 +17,13 @@
...
@@ -17,9 +17,13 @@
"babel-preset-es2015"
:
"^6.24.0"
,
"babel-preset-es2015"
:
"^6.24.0"
,
"babel-plugin-transform-object-assign"
:
"^6.22.0"
,
"babel-plugin-transform-object-assign"
:
"^6.22.0"
,
"babel-eslint"
:
"^7.1.1"
,
"babel-eslint"
:
"^7.1.1"
,
"babel-preset-env"
:
"^1.6.1"
,
"babel-preset-stage-0"
:
"^6.24.1"
,
"babelify"
:
"^7.3.0"
,
"babelify"
:
"^7.3.0"
,
"fast-async"
:
"^6.1.2"
,
"fast-async"
:
"^6.1.2"
,
"ethereumjs-util"
:
"^4.5.0"
,
"ethereumjs-util"
:
"^5.1.2"
,
"ethereumjs-abi"
:
"https://github.com/ethereumjs/ethereumjs-abi"
,
"ethereumjs-vm"
:
"2.3.1"
,
"web3"
:
"^0.15.3"
,
"web3"
:
"^0.15.3"
,
"solc"
:
"^0.4.13"
,
"solc"
:
"^0.4.13"
,
"standard"
:
"^7.0.1"
,
"standard"
:
"^7.0.1"
,
...
...
remix-lib/src/execution/eventsDecoder.js
0 → 100644
View file @
51d58133
'use strict'
var
ethJSABI
=
require
(
'ethereumjs-abi'
)
var
txHelper
=
require
(
'./txHelper'
)
/**
* Register to txListener and extract events
*
*/
class
EventsDecoder
{
constructor
(
opt
=
{})
{
this
.
_api
=
opt
.
api
}
/**
* use Transaction Receipt to decode logs. assume that the transaction as already been resolved by txListener.
* logs are decoded only if the contract if known by remix.
*
* @param {Object} tx - transaction object
* @param {Function} cb - callback
*/
parseLogs
(
tx
,
contractName
,
compiledContracts
,
cb
)
{
if
(
tx
.
isCall
)
return
cb
(
null
,
{
decoded
:
[],
raw
:
[]
})
this
.
_api
.
resolveReceipt
(
tx
,
(
error
,
receipt
)
=>
{
if
(
error
)
return
cb
(
error
)
this
.
_decodeLogs
(
tx
,
receipt
,
contractName
,
compiledContracts
,
cb
)
})
}
_decodeLogs
(
tx
,
receipt
,
contract
,
contracts
,
cb
)
{
if
(
!
contract
||
!
receipt
)
{
return
cb
(
'cannot decode logs - contract or receipt not resolved '
)
}
if
(
!
receipt
.
logs
)
{
return
cb
(
null
,
{
decoded
:
[],
raw
:
[]
})
}
this
.
_decodeEvents
(
tx
,
receipt
.
logs
,
contract
,
contracts
,
cb
)
}
_eventABI
(
contract
)
{
var
eventABI
=
{}
contract
.
abi
.
forEach
(
function
(
funABI
,
i
)
{
if
(
funABI
.
type
!==
'event'
)
{
return
}
var
hash
=
ethJSABI
.
eventID
(
funABI
.
name
,
funABI
.
inputs
.
map
(
function
(
item
)
{
return
item
.
type
}))
eventABI
[
hash
.
toString
(
'hex'
)]
=
{
event
:
funABI
.
name
,
inputs
:
funABI
.
inputs
}
})
return
eventABI
}
_eventsABI
(
compiledContracts
)
{
var
eventsABI
=
{}
txHelper
.
visitContracts
(
compiledContracts
,
(
contract
)
=>
{
eventsABI
[
contract
.
name
]
=
this
.
_eventABI
(
contract
.
object
)
})
return
eventsABI
}
_event
(
hash
,
eventsABI
)
{
for
(
var
k
in
eventsABI
)
{
if
(
eventsABI
[
k
][
hash
])
{
return
eventsABI
[
k
][
hash
]
}
}
return
null
}
_decodeEvents
(
tx
,
logs
,
contractName
,
compiledContracts
,
cb
)
{
var
eventsABI
=
this
.
_eventsABI
(
compiledContracts
)
var
events
=
[]
for
(
var
i
in
logs
)
{
// [address, topics, mem]
var
log
=
logs
[
i
]
var
topicId
=
log
.
topics
[
0
]
var
abi
=
this
.
_event
(
topicId
.
replace
(
'0x'
,
''
),
eventsABI
)
if
(
abi
)
{
var
event
try
{
var
decoded
=
new
Array
(
abi
.
inputs
.
length
)
event
=
abi
.
event
var
indexed
=
1
var
nonindexed
=
[]
// decode indexed param
abi
.
inputs
.
map
(
function
(
item
,
index
)
{
if
(
item
.
indexed
)
{
var
encodedData
=
log
.
topics
[
indexed
].
replace
(
'0x'
,
''
)
try
{
decoded
[
index
]
=
ethJSABI
.
rawDecode
([
item
.
type
],
new
Buffer
(
encodedData
,
'hex'
))[
0
]
if
(
typeof
decoded
[
index
]
!==
'string'
)
{
decoded
[
index
]
=
ethJSABI
.
stringify
([
item
.
type
],
decoded
[
index
])
}
}
catch
(
e
)
{
decoded
[
index
]
=
encodedData
}
indexed
++
}
else
{
nonindexed
.
push
(
item
.
type
)
}
})
// decode non indexed param
var
nonindexededResult
=
ethJSABI
.
rawDecode
(
nonindexed
,
new
Buffer
(
log
.
data
.
replace
(
'0x'
,
''
),
'hex'
))
nonindexed
=
ethJSABI
.
stringify
(
nonindexed
,
nonindexededResult
)
// ordering
var
j
=
0
abi
.
inputs
.
map
(
function
(
item
,
index
)
{
if
(
!
item
.
indexed
)
{
decoded
[
index
]
=
nonindexed
[
j
]
j
++
}
})
}
catch
(
e
)
{
decoded
=
log
.
data
}
events
.
push
({
topic
:
topicId
,
event
:
event
,
args
:
decoded
})
}
else
{
events
.
push
({
data
:
log
.
data
,
topics
:
log
.
topics
})
}
}
cb
(
null
,
{
decoded
:
events
,
raw
:
logs
})
}
}
module
.
exports
=
EventsDecoder
remix-lib/src/execution/execution-context.js
0 → 100644
View file @
51d58133
'use strict'
var
Web3
=
require
(
'web3'
)
var
EventManager
=
require
(
'../eventManager'
)
var
EthJSVM
=
require
(
'ethereumjs-vm'
)
var
ethUtil
=
require
(
'ethereumjs-util'
)
var
StateManager
=
require
(
'ethereumjs-vm/lib/stateManager'
)
var
Web3VMProvider
=
require
(
'../web3Provider/web3VmProvider'
)
var
rlp
=
ethUtil
.
rlp
var
injectedProvider
var
web3
if
(
typeof
window
!==
'undefined'
&&
typeof
window
.
web3
!==
'undefined'
)
{
injectedProvider
=
window
.
web3
.
currentProvider
web3
=
new
Web3
(
injectedProvider
)
}
else
{
web3
=
new
Web3
(
new
Web3
.
providers
.
HttpProvider
(
'http://localhost:8545'
))
}
var
blankWeb3
=
new
Web3
()
/*
extend vm state manager and instanciate VM
*/
class
StateManagerCommonStorageDump
extends
StateManager
{
constructor
(
arg
)
{
super
(
arg
)
this
.
keyHashes
=
{}
}
putContractStorage
(
address
,
key
,
value
,
cb
)
{
this
.
keyHashes
[
ethUtil
.
sha3
(
key
).
toString
(
'hex'
)]
=
ethUtil
.
bufferToHex
(
key
)
super
.
putContractStorage
(
address
,
key
,
value
,
cb
)
}
dumpStorage
(
address
,
cb
)
{
var
self
=
this
this
.
_getStorageTrie
(
address
,
function
(
err
,
trie
)
{
if
(
err
)
{
return
cb
(
err
)
}
var
storage
=
{}
var
stream
=
trie
.
createReadStream
()
stream
.
on
(
'data'
,
function
(
val
)
{
var
value
=
rlp
.
decode
(
val
.
value
)
storage
[
'0x'
+
val
.
key
.
toString
(
'hex'
)]
=
{
key
:
self
.
keyHashes
[
val
.
key
.
toString
(
'hex'
)],
value
:
'0x'
+
value
.
toString
(
'hex'
)
}
})
stream
.
on
(
'end'
,
function
()
{
cb
(
storage
)
})
})
}
}
var
stateManager
=
new
StateManagerCommonStorageDump
({})
var
vm
=
new
EthJSVM
({
enableHomestead
:
true
,
activatePrecompiles
:
true
})
// FIXME: move state manager in EthJSVM ctr
vm
.
stateManager
=
stateManager
vm
.
blockchain
=
stateManager
.
blockchain
vm
.
trie
=
stateManager
.
trie
vm
.
stateManager
.
checkpoint
()
var
web3VM
=
new
Web3VMProvider
()
web3VM
.
setVM
(
vm
)
var
mainNetGenesisHash
=
'0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3'
/*
trigger contextChanged, web3EndpointChanged
*/
function
ExecutionContext
()
{
var
self
=
this
this
.
event
=
new
EventManager
()
var
executionContext
=
null
this
.
init
=
function
(
config
)
{
if
(
config
.
get
(
'settings/always-use-vm'
))
{
executionContext
=
'vm'
}
else
{
executionContext
=
injectedProvider
?
'injected'
:
'vm'
}
}
this
.
getProvider
=
function
()
{
return
executionContext
}
this
.
isVM
=
function
()
{
return
executionContext
===
'vm'
}
this
.
web3
=
function
()
{
return
this
.
isVM
()
?
web3VM
:
web3
}
this
.
detectNetwork
=
function
(
callback
)
{
if
(
this
.
isVM
())
{
callback
(
null
,
{
id
:
'-'
,
name
:
'VM'
})
}
else
{
this
.
web3
().
version
.
getNetwork
((
err
,
id
)
=>
{
var
name
=
null
if
(
err
)
name
=
'Unknown'
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md
else
if
(
id
===
'1'
)
name
=
'Main'
else
if
(
id
===
'2'
)
name
=
'Morden (deprecated)'
else
if
(
id
===
'3'
)
name
=
'Ropsten'
else
if
(
id
===
'4'
)
name
=
'Rinkeby'
else
if
(
id
===
'42'
)
name
=
'Kovan'
else
name
=
'Custom'
if
(
id
===
'1'
)
{
this
.
web3
().
eth
.
getBlock
(
0
,
(
error
,
block
)
=>
{
if
(
error
)
console
.
log
(
'cant query first block'
)
if
(
block
&&
block
.
hash
!==
mainNetGenesisHash
)
name
=
'Custom'
callback
(
err
,
{
id
,
name
})
})
}
else
{
callback
(
err
,
{
id
,
name
})
}
})
}
}
this
.
internalWeb3
=
function
()
{
return
web3
}
this
.
blankWeb3
=
function
()
{
return
blankWeb3
}
this
.
vm
=
function
()
{
return
vm
}
this
.
setContext
=
function
(
context
,
endPointUrl
,
confirmCb
,
infoCb
)
{
executionContext
=
context
this
.
executionContextChange
(
context
,
endPointUrl
,
confirmCb
,
infoCb
)
}
this
.
executionContextChange
=
function
(
context
,
endPointUrl
,
confirmCb
,
infoCb
,
cb
)
{
if
(
!
cb
)
cb
=
()
=>
{}
if
(
context
===
'vm'
)
{
executionContext
=
context
vm
.
stateManager
.
revert
(
function
()
{
vm
.
stateManager
.
checkpoint
()
})
self
.
event
.
trigger
(
'contextChanged'
,
[
'vm'
])
return
cb
()
}
if
(
context
===
'injected'
)
{
if
(
injectedProvider
===
undefined
)
{
var
alertMsg
=
'No injected Web3 provider found. '
alertMsg
+=
'Make sure your provider (e.g. MetaMask) is active and running '
alertMsg
+=
'(when recently activated you may have to reload the page).'
infoCb
(
alertMsg
)
return
cb
()
}
else
{
executionContext
=
context
web3
.
setProvider
(
injectedProvider
)
self
.
event
.
trigger
(
'contextChanged'
,
[
'injected'
])
return
cb
()
}
}
if
(
context
===
'web3'
)
{
confirmCb
(
cb
)
}
}
this
.
currentblockGasLimit
=
function
()
{
return
this
.
blockGasLimit
}
this
.
blockGasLimitDefault
=
4300000
this
.
blockGasLimit
=
this
.
blockGasLimitDefault
setInterval
(()
=>
{
if
(
this
.
getProvider
()
!==
'vm'
)
{
web3
.
eth
.
getBlock
(
'latest'
,
(
err
,
block
)
=>
{
if
(
!
err
)
{
// we can't use the blockGasLimit cause the next blocks could have a lower limit : https://github.com/ethereum/remix/issues/506
this
.
blockGasLimit
=
(
block
&&
block
.
gasLimit
)
?
Math
.
floor
(
block
.
gasLimit
-
(
5
*
block
.
gasLimit
)
/
1024
)
:
this
.
blockGasLimitDefault
}
else
{
this
.
blockGasLimit
=
this
.
blockGasLimitDefault
}
})
}
},
15000
)
// TODO: not used here anymore and needs to be moved
function
setProviderFromEndpoint
(
endpoint
,
context
,
cb
)
{
var
oldProvider
=
web3
.
currentProvider
if
(
endpoint
===
'ipc'
)
{
web3
.
setProvider
(
new
web3
.
providers
.
IpcProvider
())
}
else
{
web3
.
setProvider
(
new
web3
.
providers
.
HttpProvider
(
endpoint
))
}
if
(
web3
.
isConnected
())
{
executionContext
=
context
self
.
event
.
trigger
(
'contextChanged'
,
[
'web3'
])
self
.
event
.
trigger
(
'web3EndpointChanged'
)
cb
()
}
else
{
web3
.
setProvider
(
oldProvider
)
var
alertMsg
=
'Not possible to connect to the Web3 provider. '
alertMsg
+=
'Make sure the provider is running and a connection is open (via IPC or RPC).'
cb
(
alertMsg
)
}
}
this
.
setProviderFromEndpoint
=
setProviderFromEndpoint
}
module
.
exports
=
new
ExecutionContext
()
remix-lib/src/execution/txExecution.js
0 → 100644
View file @
51d58133
'use strict'
module
.
exports
=
{
/**
* deploy the given contract
*
* @param {String} data - data to send with the transaction ( return of txFormat.buildData(...) ).
* @param {Object} udap - udapp.
* @param {Function} callback - callback.
*/
createContract
:
function
(
data
,
udapp
,
callback
)
{
udapp
.
runTx
({
data
:
data
,
useCall
:
false
},
(
error
,
txResult
)
=>
{
// see universaldapp.js line 660 => 700 to check possible values of txResult (error case)
callback
(
error
,
txResult
)
})
},
/**
* call the current given contract
*
* @param {String} to - address of the contract to call.
* @param {String} data - data to send with the transaction ( return of txFormat.buildData(...) ).
* @param {Object} funAbi - abi definition of the function to call.
* @param {Object} udap - udapp.
* @param {Function} callback - callback.
*/
callFunction
:
function
(
to
,
data
,
funAbi
,
udapp
,
callback
)
{
udapp
.
runTx
({
to
:
to
,
data
:
data
,
useCall
:
funAbi
.
constant
},
(
error
,
txResult
)
=>
{
// see universaldapp.js line 660 => 700 to check possible values of txResult (error case)
callback
(
error
,
txResult
)
})
},
/**
* check if the vm has errored
*
* @param {Object} txResult - the value returned by the vm
* @return {Object} - { error: true/false, message: DOMNode }
*/
checkVMError
:
function
(
txResult
)
{
var
errorCode
=
{
OUT_OF_GAS
:
'out of gas'
,
STACK_UNDERFLOW
:
'stack underflow'
,
STACK_OVERFLOW
:
'stack overflow'
,
INVALID_JUMP
:
'invalid JUMP'
,
INVALID_OPCODE
:
'invalid opcode'
,
REVERT
:
'revert'
,
STATIC_STATE_CHANGE
:
'static state change'
}
var
ret
=
{
error
:
false
,
message
:
''
}
if
(
!
txResult
.
result
.
vm
.
exceptionError
)
{
return
ret
}
var
error
=
`VM error:
${
txResult
.
result
.
vm
.
exceptionError
}
.\n`
var
msg
if
(
txResult
.
result
.
vm
.
exceptionError
===
errorCode
.
INVALID_OPCODE
)
{
msg
=
`\t\n\tThe execution might have thrown.\n`
ret
.
error
=
true
}
else
if
(
txResult
.
result
.
vm
.
exceptionError
===
errorCode
.
OUT_OF_GAS
)
{
msg
=
`\tThe transaction ran out of gas. Please increase the Gas Limit.\n`
ret
.
error
=
true
}
else
if
(
txResult
.
result
.
vm
.
exceptionError
===
errorCode
.
REVERT
)
{
msg
=
`\tThe transaction has been reverted to the initial state.\nNote: The constructor should be payable if you send value.`
ret
.
error
=
true
}
else
if
(
txResult
.
result
.
vm
.
exceptionError
===
errorCode
.
STATIC_STATE_CHANGE
)
{
msg
=
`\tState changes is not allowed in Static Call context\n`
ret
.
error
=
true
}
ret
.
message
=
`
${
error
}${
txResult
.
result
.
vm
.
exceptionError
}${
msg
}
\tDebug the transaction to get more information.`
return
ret
}
}
remix-lib/src/execution/txFormat.js
0 → 100644
View file @
51d58133
'use strict'
var
ethJSABI
=
require
(
'ethereumjs-abi'
)
var
helper
=
require
(
'./txHelper'
)
var
executionContext
=
require
(
'./execution-context'
)
module
.
exports
=
{
/**
* build the transaction data
*
* @param {Object} function abi
* @param {Object} values to encode
* @param {String} contractbyteCode
*/
encodeData
:
function
(
funABI
,
values
,
contractbyteCode
)
{
var
encoded
var
encodedHex
try
{
encoded
=
helper
.
encodeParams
(
funABI
,
values
)
encodedHex
=
encoded
.
toString
(
'hex'
)
}
catch
(
e
)
{
return
{
error
:
'cannot encode arguments'
}
}
if
(
contractbyteCode
)
{
return
{
data
:
contractbyteCode
+
encodedHex
}
}
else
{
return
{
data
:
Buffer
.
concat
([
helper
.
encodeFunctionId
(
funABI
),
encoded
]).
toString
(
'hex'
)
}
}
},
/**
* build the transaction data
*
* @param {String} contractName
* @param {Object} contract - abi definition of the current contract.
* @param {Object} contracts - map of all compiled contracts.
* @param {Bool} isConstructor - isConstructor.
* @param {Object} funAbi - abi definition of the function to call. null if building data for the ctor.
* @param {Object} params - input paramater of the function to call
* @param {Object} udapp - udapp
* @param {Function} callback - callback
* @param {Function} callbackStep - callbackStep
*/
buildData
:
function
(
contractName
,
contract
,
contracts
,
isConstructor
,
funAbi
,
params
,
udapp
,
callback
,
callbackStep
)
{
var
funArgs
=
''
var
data
=
''
var
dataHex
=
''
if
(
params
.
indexOf
(
'0x'
)
===
0
)
{
dataHex
=
params
.
replace
(
'0x'
,
''
)
data
=
Buffer
.
from
(
dataHex
,
'hex'
)
}
else
{
try
{
funArgs
=
JSON
.
parse
(
'['
+
params
+
']'
)
}
catch
(
e
)
{
callback
(
'Error encoding arguments: '
+
e
)
return
}
if
(
!
isConstructor
||
funArgs
.
length
>
0
)
{
try
{
data
=
helper
.
encodeParams
(
funAbi
,
funArgs
)
dataHex
=
data
.
toString
(
'hex'
)
}
catch
(
e
)
{
callback
(
'Error encoding arguments: '
+
e
)
return
}
}
if
(
data
.
slice
(
0
,
9
)
===
'undefined'
)
{
dataHex
=
data
.
slice
(
9
)
}
if
(
data
.
slice
(
0
,
2
)
===
'0x'
)
{
dataHex
=
data
.
slice
(
2
)
}
}
var
contractBytecode
if
(
isConstructor
)
{
contractBytecode
=
contract
.
evm
.
bytecode
.
object
var
bytecodeToDeploy
=
contract
.
evm
.
bytecode
.
object
if
(
bytecodeToDeploy
.
indexOf
(
'_'
)
>=
0
)
{
this
.
linkBytecode
(
contract
,
contracts
,
udapp
,
(
err
,
bytecode
)
=>
{
if
(
err
)
{
callback
(
'Error deploying required libraries: '
+
err
)
}
else
{
bytecodeToDeploy
=
bytecode
+
dataHex
return
callback
(
null
,
{
dataHex
:
bytecodeToDeploy
,
funAbi
,
funArgs
,
contractBytecode
,
contractName
:
contractName
})
}
},
callbackStep
)
return
}
else
{
dataHex
=
bytecodeToDeploy
+
dataHex
}
}
else
{
dataHex
=
Buffer
.
concat
([
helper
.
encodeFunctionId
(
funAbi
),
data
]).
toString
(
'hex'
)
}
callback
(
null
,
{
dataHex
,
funAbi
,
funArgs
,
contractBytecode
,
contractName
:
contractName
})
},
atAddress
:
function
()
{},
linkBytecode
:
function
(
contract
,
contracts
,
udapp
,
callback
,
callbackStep
)
{
if
(
contract
.
evm
.
bytecode
.
object
.
indexOf
(
'_'
)
<
0
)
{
return
callback
(
null
,
contract
.
evm
.
bytecode
.
object
)
}
var
libraryRefMatch
=
contract
.
evm
.
bytecode
.
object
.
match
(
/__
([^
_
]{1,36})
__/
)
if
(
!
libraryRefMatch
)
{
return
callback
(
'Invalid bytecode format.'
)
}
var
libraryName
=
libraryRefMatch
[
1
]
// file_name:library_name
var
libRef
=
libraryName
.
match
(
/
(
.*
)
:
(
.*
)
/
)
if
(
!
libRef
)
{
return
callback
(
'Cannot extract library reference '
+
libraryName
)
}
if
(
!
contracts
[
libRef
[
1
]]
||
!
contracts
[
libRef
[
1
]][
libRef
[
2
]])
{
return
callback
(
'Cannot find library reference '
+
libraryName
)
}
var
libraryShortName
=
libRef
[
2
]
var
library
=
contracts
[
libRef
[
1
]][
libraryShortName
]
if
(
!
library
)
{
return
callback
(
'Library '
+
libraryName
+
' not found.'
)
}
this
.
deployLibrary
(
libraryName
,
libraryShortName
,
library
,
contracts
,
udapp
,
(
err
,
address
)
=>
{
if
(
err
)
{
return
callback
(
err
)
}
var
hexAddress
=
address
.
toString
(
'hex'
)
if
(
hexAddress
.
slice
(
0
,
2
)
===
'0x'
)
{
hexAddress
=
hexAddress
.
slice
(
2
)
}
contract
.
evm
.
bytecode
.
object
=
this
.
linkLibraryStandard
(
libraryShortName
,
hexAddress
,
contract
)
contract
.
evm
.
bytecode
.
object
=
this
.
linkLibrary
(
libraryName
,
hexAddress
,
contract
.
evm
.
bytecode
.
object
)
this
.
linkBytecode
(
contract
,
contracts
,
udapp
,
callback
,
callbackStep
)
},
callbackStep
)
},
deployLibrary
:
function
(
libraryName
,
libraryShortName
,
library
,
contracts
,
udapp
,
callback
,
callbackStep
)
{
var
address
=
library
.
address
if
(
address
)
{
return
callback
(
null
,
address
)
}
var
bytecode
=
library
.
evm
.
bytecode
.
object
if
(
bytecode
.
indexOf
(
'_'
)
>=
0
)
{
this
.
linkBytecode
(
library
,
contracts
,
udapp
,
(
err
,
bytecode
)
=>
{
if
(
err
)
callback
(
err
)
else
this
.
deployLibrary
(
libraryName
,
libraryShortName
,
library
,
contracts
,
udapp
,
callback
,
callbackStep
)
},
callbackStep
)
}
else
{
callbackStep
(
`creation of library
${
libraryName
}
pending...`
)
var
data
=
{
dataHex
:
bytecode
,
funAbi
:
{
type
:
'constructor'
},
funArgs
:
[],
contractBytecode
:
bytecode
,
contractName
:
libraryShortName
}
udapp
.
runTx
({
data
:
data
,
useCall
:
false
},
(
err
,
txResult
)
=>
{
if
(
err
)
{
return
callback
(
err
)
}
var
address
=
executionContext
.
isVM
()
?
txResult
.
result
.
createdAddress
:
txResult
.
result
.
contractAddress
library
.
address
=
address
callback
(
err
,
address
)
})
}
},
linkLibraryStandardFromlinkReferences
:
function
(
libraryName
,
address
,
bytecode
,
linkReferences
)
{
for
(
var
file
in
linkReferences
)
{
for
(
var
libName
in
linkReferences
[
file
])
{
if
(
libraryName
===
libName
)
{
bytecode
=
this
.
setLibraryAddress
(
address
,
bytecode
,
linkReferences
[
file
][
libName
])
}
}
}
return
bytecode
},
linkLibraryStandard
:
function
(
libraryName
,
address
,
contract
)
{
return
this
.
linkLibraryStandardFromlinkReferences
(
libraryName
,
address
,
contract
.
evm
.
bytecode
.
object
,
contract
.
evm
.
bytecode
.
linkReferences
)
},
setLibraryAddress
:
function
(
address
,
bytecodeToLink
,
positions
)
{
if
(
positions
)
{
for
(
var
pos
of
positions
)
{
var
regpos
=
bytecodeToLink
.
match
(
new
RegExp
(
`(.{
${
2
*
pos
.
start
}
})(.{
${
2
*
pos
.
length
}
})(.*)`
))
if
(
regpos
)
{
bytecodeToLink
=
regpos
[
1
]
+
address
+
regpos
[
3
]
}
}
}
return
bytecodeToLink
},
linkLibrary
:
function
(
libraryName
,
address
,
bytecodeToLink
)
{
var
libLabel
=
'__'
+
libraryName
+
Array
(
39
-
libraryName
.
length
).
join
(
'_'
)
if
(
bytecodeToLink
.
indexOf
(
libLabel
)
===
-
1
)
return
bytecodeToLink
address
=
Array
(
40
-
address
.
length
+
1
).
join
(
'0'
)
+
address
while
(
bytecodeToLink
.
indexOf
(
libLabel
)
>=
0
)
{
bytecodeToLink
=
bytecodeToLink
.
replace
(
libLabel
,
address
)
}
return
bytecodeToLink
},
decodeResponse
:
function
(
response
,
fnabi
)
{
// Only decode if there supposed to be fields
if
(
fnabi
.
outputs
&&
fnabi
.
outputs
.
length
>
0
)
{
try
{
var
i
var
outputTypes
=
[]
for
(
i
=
0
;
i
<
fnabi
.
outputs
.
length
;
i
++
)
{
outputTypes
.
push
(
fnabi
.
outputs
[
i
].
type
)
}
// decode data
var
decodedObj
=
ethJSABI
.
rawDecode
(
outputTypes
,
response
)
// format decoded data
decodedObj
=
ethJSABI
.
stringify
(
outputTypes
,
decodedObj
)
var
json
=
{}
for
(
i
=
0
;
i
<
outputTypes
.
length
;
i
++
)
{
var
name
=
fnabi
.
outputs
[
i
].
name
json
[
i
]
=
outputTypes
[
i
]
+
': '
+
(
name
?
name
+
' '
+
decodedObj
[
i
]
:
decodedObj
[
i
])
}
return
json
}
catch
(
e
)
{
return
{
error
:
'Failed to decode output: '
+
e
}
}
}
return
{}
}
}
remix-lib/src/execution/txHelper.js
0 → 100644
View file @
51d58133
'use strict'
var
ethJSABI
=
require
(
'ethereumjs-abi'
)
module
.
exports
=
{
encodeParams
:
function
(
funABI
,
args
)
{
var
types
=
[]
if
(
funABI
.
inputs
&&
funABI
.
inputs
.
length
)
{
for
(
var
i
=
0
;
i
<
funABI
.
inputs
.
length
;
i
++
)
{
var
type
=
funABI
.
inputs
[
i
].
type
types
.
push
(
type
)
if
(
args
.
length
<
types
.
length
)
{
args
.
push
(
''
)
}
}
}
// NOTE: the caller will concatenate the bytecode and this
// it could be done here too for consistency
return
ethJSABI
.
rawEncode
(
types
,
args
)
},
encodeFunctionId
:
function
(
funABI
)
{
var
types
=
[]
if
(
funABI
.
inputs
&&
funABI
.
inputs
.
length
)
{
for
(
var
i
=
0
;
i
<
funABI
.
inputs
.
length
;
i
++
)
{
types
.
push
(
funABI
.
inputs
[
i
].
type
)
}
}
return
ethJSABI
.
methodID
(
funABI
.
name
,
types
)
},
sortAbiFunction
:
function
(
contractabi
)
{
var
abi
=
contractabi
.
sort
(
function
(
a
,
b
)
{
if
(
a
.
name
>
b
.
name
)
{
return
-
1
}
else
{
return
1
}
}).
sort
(
function
(
a
,
b
)
{
if
(
a
.
constant
===
true
)
{
return
-
1
}
else
{
return
1
}
})
return
abi
},
getConstructorInterface
:
function
(
abi
)
{
var
funABI
=
{
'name'
:
''
,
'inputs'
:
[],
'type'
:
'constructor'
,
'outputs'
:
[]
}
if
(
typeof
abi
===
'string'
)
{
try
{
abi
=
JSON
.
parse
(
abi
)
}
catch
(
e
)
{
console
.
log
(
'exception retrieving ctor abi '
+
abi
)
return
funABI
}
}
for
(
var
i
=
0
;
i
<
abi
.
length
;
i
++
)
{
if
(
abi
[
i
].
type
===
'constructor'
)
{
funABI
.
inputs
=
abi
[
i
].
inputs
||
[]
break
}
}
return
funABI
},
getFunction
:
function
(
abi
,
fnName
)
{
for
(
var
i
=
0
;
i
<
abi
.
length
;
i
++
)
{
if
(
abi
[
i
].
name
===
fnName
)
{
return
abi
[
i
]
}
}
return
null
},
getFallbackInterface
:
function
(
abi
)
{
for
(
var
i
=
0
;
i
<
abi
.
length
;
i
++
)
{
if
(
abi
[
i
].
type
===
'fallback'
)
{
return
abi
[
i
]
}
}
},
/**
* return the contract obj of the given @arg name. Uses last compilation result.
* return null if not found
* @param {String} name - contract name
* @returns contract obj and associated file: { contract, file } or null
*/
getContract
:
(
contractName
,
contracts
)
=>
{
for
(
var
file
in
contracts
)
{
if
(
contracts
[
file
][
contractName
])
{
return
{
object
:
contracts
[
file
][
contractName
],
file
:
file
}
}
}
return
null
},
/**
* call the given @arg cb (function) for all the contracts. Uses last compilation result
* stop visiting when cb return true
* @param {Function} cb - callback
*/
visitContracts
:
(
contracts
,
cb
)
=>
{
for
(
var
file
in
contracts
)
{
for
(
var
name
in
contracts
[
file
])
{
if
(
cb
({
name
:
name
,
object
:
contracts
[
file
][
name
],
file
:
file
}))
return
}
}
},
inputParametersDeclarationToString
:
function
(
abiinputs
)
{
var
inputs
=
(
abiinputs
||
[]).
map
((
inp
)
=>
inp
.
type
+
' '
+
inp
.
name
)
return
inputs
.
join
(
', '
)
}
}
remix-lib/src/execution/txListener.js
0 → 100644
View file @
51d58133
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment