ethereumjs-util#BN TypeScript Examples
The following examples show how to use
ethereumjs-util#BN.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: util.ts From remix-project with MIT License | 7 votes |
export function toBN (value) {
if (value instanceof BN) {
return value
} else if (value.match && value.match(/^(0x)?([a-f0-9]*)$/)) {
value = unpadHexString(value)
value = new BN(value === '' ? '0' : value, 16)
} else if (!isNaN(value)) {
value = new BN(value)
}
return value
}
Example #2
Source File: util.ts From remix-project with MIT License | 7 votes |
/*
ints: list of BNs
*/
export function hexListFromBNs (bnList) {
const ret = []
for (const k in bnList) {
const v = bnList[k]
if (BN.isBN(v)) {
ret.push('0x' + v.toString('hex', 64))
} else {
ret.push('0x' + (new BN(v)).toString('hex', 64)) // TEMP FIX TO REMOVE ONCE https://github.com/ethereumjs/ethereumjs-vm/pull/293 is released
}
}
return ret
}
Example #3
Source File: DynamicByteArray.ts From remix-project with MIT License | 6 votes |
async decodeFromStorage (location, storageResolver) {
let value = '0x0'
try {
value = await extractHexValue(location, storageResolver, this.storageBytes)
} catch (e) {
console.log(e)
return { error: '<decoding failed - ' + e.message + '>', type: this.typeName }
}
const length = new BN(value, 16)
if (length.testn(0)) {
let dataPos = new BN(sha3256(location.slot).replace('0x', ''), 16)
let ret = ''
let currentSlot = '0x'
try {
currentSlot = await readFromStorage(dataPos, storageResolver)
} catch (e) {
console.log(e)
return { error: '<decoding failed - ' + e.message + '>', type: this.typeName }
}
while (length.gt(new BN(ret.length)) && ret.length < 32000) {
currentSlot = currentSlot.replace('0x', '')
ret += currentSlot
dataPos = dataPos.add(new BN(1))
try {
currentSlot = await readFromStorage(dataPos, storageResolver)
} catch (e) {
console.log(e)
return { error: '<decoding failed - ' + e.message + '>', type: this.typeName }
}
}
return { value: '0x' + ret.replace(/(00)+$/, ''), length: '0x' + length.toString(16), type: this.typeName }
} else {
const size = parseInt(value.substr(value.length - 2, 2), 16) / 2
return { value: '0x' + value.substr(0, size * 2), length: '0x' + size.toString(16), type: this.typeName }
}
}
Example #4
Source File: get-common.ts From cloud-cryptographic-wallet with MIT License | 6 votes |
export async function getCommon(rpcUrl: string): Promise<CommonType> {
const chainId = await query<string>(rpcUrl, "eth_chainId", []);
if (!chainId) {
throw new Error("getCommon: can't get result of eth_chainId");
}
return Common.custom({
chainId: new BN(chainId.slice(2), "hex"),
defaultHardfork: Hardfork.London,
});
}
Example #5
Source File: global-variables.tsx From remix-project with MIT License | 6 votes |
GlobalVariables = ({ block, receipt, tx }) => {
// see https://docs.soliditylang.org/en/latest/units-and-global-variables.html#block-and-transaction-properties
const globals = {
'block.chainid': tx.chainId,
'block.coinbase': block.miner,
'block.difficulty': block.difficulty,
'block.gaslimit': block.gasLimit,
'block.number': block.number,
'block.timestamp': block.timestamp,
'msg.sender': tx.from,
'msg.sig': tx.input.substring(0, 10),
'msg.value': tx.value + ' Wei',
'tx.origin': tx.from
}
if (block.baseFeePerGas) {
globals['block.basefee'] = (new BN(block.baseFeePerGas.replace('0x', ''), 'hex')).toString(10) + ` Wei (${block.baseFeePerGas})`
}
return (
<div id='globalvariable' data-id='globalvariable'>
<DropdownPanel hexHighlight={false} bodyStyle={{ fontFamily: 'monospace' }} dropdownName='Global Variables' calldata={globals || {}} />
</div>
)
}
Example #6
Source File: transactions.ts From remix-project with MIT License | 6 votes |
eth_getTransactionCount (payload, cb) {
const address = payload.params[0]
this.vmContext.vm().stateManager.getAccount(Address.fromString(address)).then((account) => {
const nonce = new BN(account.nonce).toString(10)
cb(null, nonce)
}).catch((error) => {
cb(error)
})
}
Example #7
Source File: accounts.ts From remix-project with MIT License | 6 votes |
eth_getBalance (payload, cb) {
const address = payload.params[0]
this.vmContext.vm().stateManager.getAccount(Address.fromString(address)).then((account) => {
cb(null, new BN(account.balance).toString(10))
}).catch((error) => {
cb(error)
})
}
Example #8
Source File: accounts.ts From remix-project with MIT License | 6 votes |
_addAccount (privateKey, balance) {
return new Promise((resolve, reject) => {
privateKey = Buffer.from(privateKey, 'hex')
const address: Buffer = privateToAddress(privateKey)
const addressStr = toChecksumAddress('0x' + address.toString('hex'))
this.accounts[addressStr] = { privateKey, nonce: 0 }
this.accountsKeys[addressStr] = '0x' + privateKey.toString('hex')
const stateManager = this.vmContext.vm().stateManager
stateManager.getAccount(Address.fromString(addressStr)).then((account) => {
account.balance = new BN(balance.replace('0x', '') || 'f00000000000000001', 16)
stateManager.putAccount(Address.fromString(addressStr), account).catch((error) => {
reject(error)
}).then(() => {
resolve({})
})
}).catch((error) => {
reject(error)
})
})
}
Example #9
Source File: genesis.ts From remix-project with MIT License | 6 votes |
export function generateBlock (vmContext) {
return new Promise((resolve, reject) => {
const block: Block = Block.fromBlockData({
header: {
timestamp: (new Date().getTime() / 1000 | 0),
number: 0,
coinbase: '0x0e9281e9c6a0808672eaba6bd1220e144c9bb07a',
difficulty: new BN('69762765929000', 10),
gasLimit: new BN('8000000').imuln(1)
}
}, { common: vmContext.vmObject().common })
vmContext.vm().runBlock({ block: block, generate: true, skipBlockValidation: true, skipBalance: false }).then(() => {
vmContext.addBlock(block)
resolve({})
}).catch((e) => reject(e))
})
}
Example #10
Source File: VmProxy.ts From remix-project with MIT License | 6 votes |
getSha3Input (stack, memory) {
let memoryStart = stack[stack.length - 1]
let memoryLength = stack[stack.length - 2]
const memStartDec = (new BN(memoryStart.replace('0x', ''), 16)).toString(10)
memoryStart = parseInt(memStartDec) * 2
const memLengthDec = (new BN(memoryLength.replace('0x', ''), 16).toString(10))
memoryLength = parseInt(memLengthDec) * 2
let i = Math.floor(memoryStart / 32)
const maxIndex = Math.floor(memoryLength / 32) + i
if (!memory[i]) {
return this.emptyFill(memoryLength)
}
let sha3Input = memory[i].slice(memoryStart - 32 * i)
i++
while (i < maxIndex) {
sha3Input += memory[i] ? memory[i] : this.emptyFill(32)
i++
}
if (sha3Input.length < memoryLength) {
const leftSize = memoryLength - sha3Input.length
sha3Input += memory[i] ? memory[i].slice(0, leftSize) : this.emptyFill(leftSize)
}
return sha3Input
}
Example #11
Source File: txResultHelper.ts From remix-project with MIT License | 6 votes |
VM_RESULT = {
receipt: {
amountSpent: new BN(1),
contractAddress: CONTRACT_ADDRESS_BUFFER,
gasRefund: new BN(0),
gasUsed: new BN(GAS_USED_INT),
status: STATUS_OK,
},
transactionHash: TRANSACTION_HASH
}
Example #12
Source File: typeConversion.ts From remix-project with MIT License | 6 votes |
function convertToString (v) {
try {
if (v instanceof Array) {
const ret = []
for (const k in v) {
ret.push(convertToString(v[k]))
}
return ret
} else if (BN.isBN(v) || (v.constructor && v.constructor.name === 'BigNumber')) {
return v.toString(10)
} else if (v._isBuffer) {
return bufferToHex(v)
} else if (typeof v === 'object') {
const retObject = {}
for (const i in v) {
retObject[i] = convertToString(v[i])
}
return retObject
} else {
return v
}
} catch (e) {
console.log(e)
return v
}
}
Example #13
Source File: util.ts From remix-project with MIT License | 6 votes |
export function decodeIntFromHex (value, byteLength, signed) {
let bigNumber = new BN(value, 16)
if (signed) {
bigNumber = bigNumber.fromTwos(8 * byteLength)
}
return bigNumber.toString(10)
}
Example #14
Source File: Mapping.ts From remix-project with MIT License | 6 votes |
function getMappingLocation (key, position) {
// mapping storage location decribed at http://solidity.readthedocs.io/en/develop/miscellaneous.html#layout-of-state-variables-in-storage
// > the value corresponding to a mapping key k is located at keccak256(k . p) where . is concatenation.
// key should be a hex string, and position an int
const mappingK = toBuffer(addHexPrefix(key))
let mappingP = toBuffer(addHexPrefix(position))
mappingP = setLengthLeft(mappingP, 32)
const mappingKeyBuf = concatTypedArrays(mappingK, mappingP)
const mappingStorageLocation: Buffer = keccak(mappingKeyBuf)
const mappingStorageLocationinBn: BN = new BN(mappingStorageLocation, 16)
return mappingStorageLocationinBn
}
Example #15
Source File: txResultHelper.ts From remix-project with MIT License | 5 votes |
EXEC_RESULT = {
exceptionError: null,
gasRefund: new BN(0),
gasUsed: new BN(GAS_USED_INT),
returnValue: RETURN_VALUE_BUFFER
}
Example #16
Source File: typeConversion.ts From remix-project with MIT License | 5 votes |
export function toInt (h) {
if (h.indexOf && h.indexOf('0x') === 0) {
return (new BN(h.replace('0x', ''), 16)).toString(10)
} else if ((h.constructor && h.constructor.name === 'BigNumber') || BN.isBN(h)) {
return h.toString(10)
}
return h
}
Example #17
Source File: solidityTypeFormatter.ts From remix-project with MIT License | 5 votes |
// eslint-disable-line
export function extractData (item, parent): ExtractData {
const ret: ExtractData = {}
if (item.isProperty || !item.type) {
return item
}
try {
if (item.type.lastIndexOf(']') === item.type.length - 1) {
ret.children = (item.value || []).map(function (item, index) {
return { key: index, value: item }
})
ret.children.unshift({
key: 'length',
value: {
self: (new BN(item.length.replace('0x', ''), 16)).toString(10),
type: 'uint',
isProperty: true
}
})
ret.isArray = true
ret.self = parent.isArray ? '' : item.type
ret.cursor = item.cursor
ret.hasNext = item.hasNext
} else if (item.type.indexOf('struct') === 0) {
ret.children = Object.keys((item.value || {})).map(function (key) {
return { key: key, value: item.value[key] }
})
ret.self = item.type
ret.isStruct = true
} else if (item.type.indexOf('mapping') === 0) {
ret.children = Object.keys((item.value || {})).map(function (key) {
return { key: key, value: item.value[key] }
})
ret.isMapping = true
ret.self = item.type
} else {
ret.children = null
ret.self = item.value
ret.type = item.type
}
} catch (e) {
console.log(e)
}
return ret
}
Example #18
Source File: value.tsx From remix-project with MIT License | 5 votes |
export function ValueUI (props: ValueProps) {
const [sendValue, setSendValue] = useState<string>(props.sendValue)
const inputValue = useRef<HTMLInputElement>({} as HTMLInputElement)
useEffect(() => {
(sendValue !== props.sendValue) && props.setSendValue(sendValue)
}, [sendValue])
const validateInputKey = (e) => {
// preventing not numeric keys
// preventing 000 case
if (!isNumeric(e.key) ||
(e.key === '0' && !parseInt(inputValue.current.value) && inputValue.current.value.length > 0)) {
e.preventDefault()
}
}
const validateValue = (e) => {
const value = e.target.value
if (!value) {
// assign 0 if given value is
// - empty
return setSendValue('0')
}
let v
try {
v = new BN(value, 10)
setSendValue(v.toString(10))
} catch (e) {
// assign 0 if given value is
// - not valid (for ex 4345-54)
// - contains only '0's (for ex 0000) copy past or edit
setSendValue('0')
}
// if giveen value is negative(possible with copy-pasting) set to 0
if (v.lt(0)) setSendValue('0')
}
return (
<div className="udapp_crow">
<label className="udapp_settingsLabel" data-id="remixDRValueLabel">Value</label>
<div className="udapp_gasValueContainer">
<input
ref={inputValue}
type="number"
min="0"
pattern="^[0-9]"
step="1"
className="form-control udapp_gasNval udapp_col2"
id="value"
data-id="dandrValue"
title="Enter the value and choose the unit"
onKeyPress={validateInputKey}
onChange={validateValue}
value={props.sendValue}
/>
<select name="unit" value={props.sendUnit} className="form-control p-1 udapp_gasNvalUnit udapp_col2_2 custom-select" id="unit" onChange={(e) => { props.setUnit((e.target.value) as 'ether' | 'finney' | 'gwei' | 'wei') }}>
<option data-unit="wei" value='wei'>Wei</option>
<option data-unit="gwei" value="gwei">Gwei</option>
<option data-unit="finney" value="finney">Finney</option>
<option data-unit="ether" value="ether">Ether</option>
</select>
</div>
</div>
)
}
Example #19
Source File: ArrayType.ts From remix-project with MIT License | 5 votes |
async decodeFromStorage (location, storageResolver) {
const ret = []
let size = null
let slotValue
try {
slotValue = await extractHexValue(location, storageResolver, this.storageBytes)
} catch (e) {
console.log(e)
return {
error: '<decoding failed - ' + e.message + '>',
type: this.typeName
}
}
const currentLocation = {
offset: 0,
slot: location.slot
}
if (this.arraySize === 'dynamic') {
size = toBN('0x' + slotValue)
currentLocation.slot = sha3256(location.slot)
} else {
size = new BN(this.arraySize)
}
const k = toBN(0)
for (; k.lt(size) && k.ltn(300); k.iaddn(1)) {
try {
ret.push(await this.underlyingType.decodeFromStorage(currentLocation, storageResolver))
} catch (e) {
return {
error: '<decoding failed - ' + e.message + '>',
type: this.typeName
}
}
if (this.underlyingType.storageSlots === 1 && location.offset + this.underlyingType.storageBytes <= 32) {
currentLocation.offset += this.underlyingType.storageBytes
if (currentLocation.offset + this.underlyingType.storageBytes > 32) {
currentLocation.offset = 0
currentLocation.slot = '0x' + add(currentLocation.slot, 1).toString(16)
}
} else {
currentLocation.slot = '0x' + add(currentLocation.slot, this.underlyingType.storageSlots).toString(16)
currentLocation.offset = 0
}
}
return { value: ret, length: '0x' + size.toString(16), type: this.typeName }
}
Example #20
Source File: abi-coder.ts From ethereum-sdk with MIT License | 5 votes |
function formatParam(type: any, param: any) {
const paramTypeBytes = new RegExp(/^bytes([0-9]*)$/)
const paramTypeBytesArray = new RegExp(/^bytes([0-9]*)\[\]$/)
const paramTypeNumber = new RegExp(/^(u?int)([0-9]*)$/)
const paramTypeNumberArray = new RegExp(/^(u?int)([0-9]*)\[\]$/)
// Format BN to string
if (BN.isBN(param) || (param && param.constructor && param.constructor.name === "BigNumber")) {
return (param as number | BN).toString(10)
}
if (type.match(paramTypeBytesArray) || type.match(paramTypeNumberArray)) {
return param.map((p: any) => formatParam(type.replace("[]", ""), p))
}
// Format correct width for u?int[0-9]*
let match = type.match(paramTypeNumber)
if (match) {
let size = parseInt(match[2] || "256")
if (size / 8 < param.length) {
// pad to correct bit width
param = ethers.utils.hexZeroPad(param, size)
}
}
// Format correct length for bytes[0-9]+
match = type.match(paramTypeBytes)
if (match) {
if (Buffer.isBuffer(param)) {
param = ethers.utils.hexlify(param)
}
// format to correct length
let size = parseInt(match[1])
if (size) {
let maxSize = size * 2
if (param.substring(0, 2) === "0x") {
maxSize += 2
}
if (param.length < maxSize) {
// pad to correct length
const rightPad = function (string: string | number, chars: number) {
const hasPrefix = typeof string === "number" || /^0x/i.test(string)
string = string.toString(16).replace(/^0x/i, "")
const padding = (chars - string.length + 1 >= 0) ? chars - string.length + 1 : 0
return (hasPrefix ? "0x" : "") + string + (new Array(padding).join("0"))
}
param = rightPad(param, size * 2)
}
}
// format odd-length bytes to even-length
if (param.length % 2 === 1) {
param = "0x0" + param.substring(2)
}
}
return param
}
Example #21
Source File: prepare-fee-for-exchange-wrapper.ts From ethereum-sdk with MIT License | 5 votes |
export function prepareForExchangeWrapperFees(fees: Part[]): string[] {
return fees.map(fee => {
const addr = stripHexPrefix(fee.account)
const preparedFee = new BN(fee.value, 10).toString(16).padStart(24, "0")
return new BN(preparedFee + addr, 16).toString(10)
})
}
Example #22
Source File: provider.ts From hardhat-kms-signer with MIT License | 5 votes |
private async _getNonce(address: Buffer): Promise<BN> {
const response = (await this._wrappedProvider.request({
method: "eth_getTransactionCount",
params: [bufferToHex(address), "pending"],
})) as string;
return rpcQuantityToBN(response);
}
Example #23
Source File: txRunnerVM.ts From remix-project with MIT License | 4 votes |
runInVm (from, to, data, value, gasLimit, useCall, timestamp, callback) {
const self = this
let account
if (!from && useCall && Object.keys(self.vmaccounts).length) {
from = Object.keys(self.vmaccounts)[0]
account = self.vmaccounts[from]
} else account = self.vmaccounts[from]
if (!account) {
return callback('Invalid account selected')
}
if (Number.isInteger(gasLimit)) {
gasLimit = '0x' + gasLimit.toString(16)
}
this.getVMObject().stateManager.getAccount(Address.fromString(from)).then((res) => {
// See https://github.com/ethereumjs/ethereumjs-tx/blob/master/docs/classes/transaction.md#constructor
// for initialization fields and their types
if (!value) value = 0
if (typeof value === 'string') {
if (value.startsWith('0x')) value = new BN(value.replace('0x', ''), 'hex')
else {
try {
value = new BN(value, 10)
} catch (e) {
return callback('Unable to parse the value ' + e.message)
}
}
}
const EIP1559 = this.commonContext.hardfork() !== 'berlin' // berlin is the only pre eip1559 fork that we handle.
let tx
if (!EIP1559) {
tx = Transaction.fromTxData({
nonce: useCall ? this.nextNonceForCall : new BN(res.nonce),
gasPrice: '0x1',
gasLimit: gasLimit,
to: to,
value: value,
data: Buffer.from(data.slice(2), 'hex')
}, { common: this.commonContext }).sign(account.privateKey)
} else {
tx = FeeMarketEIP1559Transaction.fromTxData({
nonce: useCall ? this.nextNonceForCall : new BN(res.nonce),
maxPriorityFeePerGas: '0x01',
maxFeePerGas: '0x1',
gasLimit: gasLimit,
to: to,
value: value,
data: Buffer.from(data.slice(2), 'hex')
}).sign(account.privateKey)
}
if (useCall) this.nextNonceForCall++
const coinbases = ['0x0e9281e9c6a0808672eaba6bd1220e144c9bb07a', '0x8945a1288dc78a6d8952a92c77aee6730b414778', '0x94d76e24f818426ae84aa404140e8d5f60e10e7e']
const difficulties = [new BN('69762765929000', 10), new BN('70762765929000', 10), new BN('71762765929000', 10)]
const block = Block.fromBlockData({
header: {
timestamp: timestamp || (new Date().getTime() / 1000 | 0),
number: self.blockNumber,
coinbase: coinbases[self.blockNumber % coinbases.length],
difficulty: difficulties[self.blockNumber % difficulties.length],
gasLimit: new BN(gasLimit.replace('0x', ''), 16).imuln(2),
baseFeePerGas: EIP1559 ? '0x1' : undefined
},
transactions: [tx]
}, { common: this.commonContext })
if (!useCall) {
++self.blockNumber
this.runBlockInVm(tx, block, callback)
} else {
this.getVMObject().stateManager.checkpoint().then(() => {
this.runBlockInVm(tx, block, (err, result) => {
this.getVMObject().stateManager.revert().then(() => {
callback(err, result)
})
})
})
}
}).catch((e) => {
callback(e)
})
}
Example #24
Source File: universalDappUI.tsx From remix-project with MIT License | 4 votes |
export function UniversalDappUI (props: UdappProps) {
const [toggleExpander, setToggleExpander] = useState<boolean>(true)
const [contractABI, setContractABI] = useState<FuncABI[]>(null)
const [address, setAddress] = useState<string>('')
const [expandPath, setExpandPath] = useState<string[]>([])
const [llIError, setLlIError] = useState<string>('')
const [calldataValue, setCalldataValue] = useState<string>('')
const [evmBC, setEvmBC] = useState(null)
useEffect(() => {
if (!props.instance.abi) {
const abi = txHelper.sortAbiFunction(props.instance.contractData.abi)
setContractABI(abi)
} else {
setContractABI(props.instance.abi)
}
}, [props.instance.abi])
useEffect(() => {
if (props.instance.address) {
// @ts-ignore
let address = (props.instance.address.slice(0, 2) === '0x' ? '' : '0x') + props.instance.address.toString('hex')
address = ethJSUtil.toChecksumAddress(address)
setAddress(address)
}
}, [props.instance.address])
useEffect(() => {
if (props.instance.contractData) {
setEvmBC(props.instance.contractData.bytecodeObject)
}
}, [props.instance.contractData])
const sendData = () => {
setLlIError('')
const fallback = txHelper.getFallbackInterface(contractABI)
const receive = txHelper.getReceiveInterface(contractABI)
const args = {
funcABI: fallback || receive,
address: address,
contractName: props.instance.name,
contractABI: contractABI
}
const amount = props.sendValue
if (amount !== '0') {
// check for numeric and receive/fallback
if (!isNumeric(amount)) {
return setLlIError('Value to send should be a number')
} else if (!receive && !(fallback && fallback.stateMutability === 'payable')) {
return setLlIError("In order to receive Ether transfer the contract should have either 'receive' or payable 'fallback' function")
}
}
let calldata = calldataValue
if (calldata) {
if (calldata.length < 4 && is0XPrefixed(calldata)) {
return setLlIError('The calldata should be a valid hexadecimal value with size of at least one byte.')
} else {
if (is0XPrefixed(calldata)) {
calldata = calldata.substr(2, calldata.length)
}
if (!isHexadecimal(calldata)) {
return setLlIError('The calldata should be a valid hexadecimal value.')
}
}
if (!fallback) {
return setLlIError("'Fallback' function is not defined")
}
}
if (!receive && !fallback) return setLlIError('Both \'receive\' and \'fallback\' functions are not defined')
// we have to put the right function ABI:
// if receive is defined and that there is no calldata => receive function is called
// if fallback is defined => fallback function is called
if (receive && !calldata) args.funcABI = receive
else if (fallback) args.funcABI = fallback
if (!args.funcABI) return setLlIError('Please define a \'Fallback\' function to send calldata and a either \'Receive\' or payable \'Fallback\' to send ethers')
runTransaction(false, args.funcABI, null, calldataValue)
}
const toggleClass = () => {
setToggleExpander(!toggleExpander)
}
const remove = () => {
props.removeInstance(props.index)
}
const runTransaction = (lookupOnly, funcABI: FuncABI, valArr, inputsValues, funcIndex?: number) => {
const functionName = funcABI.type === 'function' ? funcABI.name : `(${funcABI.type})`
const logMsg = `${lookupOnly ? 'call' : 'transact'} to ${props.instance.name}.${functionName}`
props.runTransactions(
props.index,
lookupOnly,
funcABI,
inputsValues,
props.instance.name,
contractABI,
props.instance.contractData,
address,
logMsg,
props.logBuilder,
props.mainnetPrompt,
props.gasEstimationPrompt,
props.passphrasePrompt,
funcIndex)
}
const extractDataDefault = (item, parent?) => {
const ret: any = {}
if (BN.isBN(item)) {
ret.self = item.toString(10)
ret.children = []
} else {
if (item instanceof Array) {
ret.children = item.map((item, index) => {
return { key: index, value: item }
})
ret.self = 'Array'
ret.isNode = true
ret.isLeaf = false
} else if (item instanceof Object) {
ret.children = Object.keys(item).map((key) => {
return { key: key, value: item[key] }
})
ret.self = 'Object'
ret.isNode = true
ret.isLeaf = false
} else {
ret.self = item
ret.children = null
ret.isNode = false
ret.isLeaf = true
}
}
return ret
}
const handleExpand = (path: string) => {
if (expandPath.includes(path)) {
const filteredPath = expandPath.filter(value => value !== path)
setExpandPath(filteredPath)
} else {
setExpandPath([...expandPath, path])
}
}
const handleCalldataChange = (e) => {
const value = e.target.value
setCalldataValue(value)
}
const label = (key: string | number, value: string) => {
return (
<div className="d-flex mt-2 flex-row label_item">
<label className="small font-weight-bold mb-0 pr-1 label_key">{key}:</label>
<label className="m-0 label_value">{value}</label>
</div>
)
}
const renderData = (item, parent, key: string | number, keyPath: string) => {
const data = extractDataDefault(item, parent)
const children = (data.children || []).map((child) => {
return (
renderData(child.value, data, child.key, keyPath + '/' + child.key)
)
})
if (children && children.length > 0) {
return (
<TreeViewItem id={`treeViewItem${key}`} key={keyPath} label={label(key, data.self)} onClick={() => handleExpand(keyPath)} expand={expandPath.includes(keyPath)}>
<TreeView id={`treeView${key}`} key={keyPath}>
{children}
</TreeView>
</TreeViewItem>
)
} else {
return <TreeViewItem id={key.toString()} key={keyPath} label={label(key, data.self)} onClick={() => handleExpand(keyPath)} expand={expandPath.includes(keyPath)} />
}
}
return (
<div className={`instance udapp_instance udapp_run-instance border-dark ${toggleExpander ? 'udapp_hidesub' : 'bg-light'}`} id={`instance${address}`} data-shared="universalDappUiInstance">
<div className="udapp_title alert alert-secondary">
<button data-id={`universalDappUiTitleExpander${props.index}`} className="btn udapp_titleExpander" onClick={toggleClass}>
<i className={`fas ${toggleExpander ? 'fa-angle-right' : 'fa-angle-down'}`} aria-hidden="true"></i>
</button>
<div className="input-group udapp_nameNbuts">
<div className="udapp_titleText input-group-prepend">
<span className="input-group-text udapp_spanTitleText">
{props.instance.name} at {shortenAddress(address)} ({props.context})
</span>
</div>
<div className="btn-group">
<button className="btn p-1 btn-secondary"><CopyToClipboard content={address} direction={'top'} /></button>
</div>
</div>
<button
className="udapp_udappClose mr-1 p-1 btn btn-secondary align-items-center"
data-id="universalDappUiUdappClose"
onClick={remove}
title="Remove from the list"
>
<i className="udapp_closeIcon fas fa-times" aria-hidden="true"></i>
</button>
</div>
<div className="udapp_cActionsWrapper" data-id="universalDappUiContractActionWrapper">
<div className="udapp_contractActionsContainer">
{
contractABI && contractABI.map((funcABI, index) => {
if (funcABI.type !== 'function') return null
const isConstant = funcABI.constant !== undefined ? funcABI.constant : false
const lookupOnly = funcABI.stateMutability === 'view' || funcABI.stateMutability === 'pure' || isConstant
const inputs = props.getFuncABIInputs(funcABI)
return <>
<ContractGUI
funcABI={funcABI}
clickCallBack={(valArray: { name: string, type: string }[], inputsValues: string) => {
runTransaction(lookupOnly, funcABI, valArray, inputsValues, index)
}}
inputs={inputs}
evmBC={evmBC}
lookupOnly={lookupOnly}
key={index}
/>
<div className="udapp_value" data-id="udapp_value">
<TreeView id="treeView">
{
Object.keys(props.instance.decodedResponse || {}).map((key) => {
const funcIndex = index.toString()
const response = props.instance.decodedResponse[key]
return key === funcIndex ? Object.keys(response || {}).map((innerkey) => {
return renderData(props.instance.decodedResponse[key][innerkey], response, innerkey, innerkey)
}) : null
})
}
</TreeView>
</div>
</>
})
}
</div>
<div className="d-flex flex-column">
<div className="d-flex flex-row justify-content-between mt-2">
<div className="py-2 border-top d-flex justify-content-start flex-grow-1">
Low level interactions
</div>
<a
href="https://solidity.readthedocs.io/en/v0.6.2/contracts.html#receive-ether-function"
title="check out docs for using 'receive'/'fallback'"
target="_blank" rel="noreferrer"
>
<i aria-hidden="true" className="fas fa-info my-2 mr-1"></i>
</a>
</div>
<div className="d-flex flex-column align-items-start">
<label className="">CALLDATA</label>
<div className="d-flex justify-content-end w-100 align-items-center">
<input id="deployAndRunLLTxCalldata" onChange={handleCalldataChange} className="udapp_calldataInput form-control" title="The Calldata to send to fallback function of the contract." />
<button id="deployAndRunLLTxSendTransaction" data-id="pluginManagerSettingsDeployAndRunLLTxSendTransaction" className="udapp_instanceButton p-0 w-50 btn border-warning text-warning" title="Send data to contract." onClick={sendData}>Transact</button>
</div>
</div>
<div>
<label id="deployAndRunLLTxError" className="text-danger my-2">{ llIError }</label>
</div>
</div>
</div>
</div>
)
}