remove withdraw locally method
DELETE
src/helpers/blocks.js
-import utils from 'ethereumjs-util'
-
-const sha3 = utils.sha3
-const BN = utils.BN
-
-export async function getHeaders(start, end, web3) {
- if (start >= end) {
- return []
- }
-
- let current = start
- let p = []
- let result = []
- while (current <= end) {
- p = []
-
- for (let i = 0; i < 10 && current <= end; i++) {
- p.push(web3.eth.getBlock(current))
- current++
- }
-
- if (p.length > 0) {
- result.push(...(await Promise.all(p)))
- }
- }
-
- return result.map(getBlockHeader)
-}
-
-export function getBlockHeader(block) {
- const n = new BN(block.number).toArrayLike(Buffer, 'be', 32)
- const ts = new BN(block.timestamp).toArrayLike(Buffer, 'be', 32)
- const txRoot = utils.toBuffer(block.transactionsRoot)
- const receiptsRoot = utils.toBuffer(block.receiptsRoot)
- return sha3(Buffer.concat([n, ts, txRoot, receiptsRoot]))
-}

DELETE
src/helpers/merkle-tree.js
-import utils from 'ethereumjs-util'
-import { Buffer } from 'safe-buffer'
-
-const sha3 = utils.sha3
-
-export default class MerkleTree {
- constructor(leaves = []) {
- if (leaves.length < 1) {
- throw new Error('Atleast 1 leaf needed')
- }
-
- const depth = Math.ceil(Math.log(leaves.length) / Math.log(2))
- if (depth > 20) {
- throw new Error('Depth must be 20 or less')
- }
-
- const l = leaves.concat(
- Array.from(Array(Math.pow(2, depth) - leaves.length), () =>
- utils.zeros(32)
- )
- )
-
- this.leaves = l
- this.layers = [l]
- this.createHashes(this.leaves)
- }
-
- createHashes(nodes) {
- if (nodes.length === 1) {
- return false
- }
-
- const treeLevel = []
- for (let i = 0; i < nodes.length; i += 2) {
- const left = nodes[i]
- const right = nodes[i + 1]
- const data = Buffer.concat([left, right])
- treeLevel.push(sha3(data))
- }
-
- // is odd number of nodes
- if (nodes.length % 2 === 1) {
- treeLevel.push(nodes[nodes.length - 1])
- }
-
- this.layers.push(treeLevel)
- this.createHashes(treeLevel)
- }
-
- getLeaves() {
- return this.leaves
- }
-
- getLayers() {
- return this.layers
- }
-
- getRoot() {
- return this.layers[this.layers.length - 1][0]
- }
-
- getProof(leaf) {
- let index = -1
- for (let i = 0; i < this.leaves.length; i++) {
- if (Buffer.compare(leaf, this.leaves[i]) === 0) {
- index = i
- }
- }
-
- const proof = []
- if (index <= this.getLeaves().length) {
- let siblingIndex
- for (let i = 0; i < this.layers.length - 1; i++) {
- if (index % 2 === 0) {
- siblingIndex = index + 1
- } else {
- siblingIndex = index - 1
- }
- index = parseInt(index / 2)
- proof.push(this.layers[i][siblingIndex])
- }
- }
- return proof
- }
-
- verify(value, index, root, proof) {
- if (!Array.isArray(proof) || !value || !root) {
- return false
- }
-
- let hash = value
- for (let i = 0; i < proof.length; i++) {
- const node = proof[i]
- if (index % 2 === 0) {
- hash = sha3(Buffer.concat([hash, node]))
- } else {
- hash = sha3(Buffer.concat([node, hash]))
- }
-
- index = parseInt(index / 2)
- }
-
- return Buffer.compare(hash, root) === 0
- }
-}

DELETE
src/helpers/proofs.js
-import Trie from 'merkle-patricia-tree'
-import utils from 'ethereumjs-util'
-import EthereumTx from 'ethereumjs-tx'
-import EthereumBlock from 'ethereumjs-block/from-rpc'
-
-import MerkleTree from './merkle-tree'
-
-const rlp = utils.rlp
-
-export function getTxBytes(tx) {
- const txObj = new EthereumTx(squanchTx(tx))
- return txObj.serialize()
-}
-
-export async function getTxProof(tx, block) {
- const txTrie = new Trie()
- for (let i = 0; i < block.transactions.length; i++) {
- const siblingTx = block.transactions[i]
- const path = rlp.encode(siblingTx.transactionIndex)
- const rawSignedSiblingTx = getTxBytes(siblingTx)
- await new Promise((resolve, reject) => {
- txTrie.put(path, rawSignedSiblingTx, err => {
- if (err) {
- reject(err)
- } else {
- resolve()
- }
- })
- })
- }
-
- // promise
- return new Promise((resolve, reject) => {
- txTrie.findPath(
- rlp.encode(tx.transactionIndex),
- (err, rawTxNode, reminder, stack) => {
- if (err) {
- return reject(err)
- }
-
- if (reminder.length > 0) {
- return reject(new Error('Node does not contain the key'))
- }
-
- const prf = {
- blockHash: utils.toBuffer(tx.blockHash),
- parentNodes: stack.map(s => s.raw),
- root: getRawHeader(block).transactionsTrie,
- path: rlp.encode(tx.transactionIndex),
- value: rlp.decode(rawTxNode.value),
- }
- resolve(prf)
- }
- )
- })
-}
-
-export function getReceiptBytes(receipt) {
- let status = receipt.root
- if (receipt.status !== undefined && receipt.status !== null) {
- status = receipt.status
- if (status === true) {
- status = '0x01'
- } else if (status === false) {
- status = '0x00'
- }
- }
-
- // raw receipt = rlp.encode([status or root, cumulativeGasUsed, logsBloom, logs])
- return rlp.encode([
- utils.toBuffer(status),
- utils.toBuffer(receipt.cumulativeGasUsed),
- utils.toBuffer(receipt.logsBloom),
-
- // encoded log array
- receipt.logs.map(l => {
- // [address, [topics array], data]
- return [
- utils.toBuffer(l.address), // convert address to buffer
- l.topics.map(utils.toBuffer), // convert topics to buffer
- utils.toBuffer(l.data), // convert data to buffer
- ]
- }),
- ])
-}
-
-export async function getReceiptProof(receipt, block, web3) {
- const receiptsTrie = new Trie()
- const receiptPromises = []
- block.transactions.forEach(tx => {
- receiptPromises.push(web3.eth.getTransactionReceipt(tx.hash))
- })
-
- const receipts = await Promise.all(receiptPromises)
- for (let i = 0; i < receipts.length; i++) {
- const siblingReceipt = receipts[i]
- const path = rlp.encode(siblingReceipt.transactionIndex)
- const rawReceipt = getReceiptBytes(siblingReceipt)
- await new Promise((resolve, reject) => {
- receiptsTrie.put(path, rawReceipt, err => {
- if (err) {
- reject(err)
- } else {
- resolve()
- }
- })
- })
- }
-
- // promise
- return new Promise((resolve, reject) => {
- receiptsTrie.findPath(
- rlp.encode(receipt.transactionIndex),
- (err, rawReceiptNode, reminder, stack) => {
- if (err) {
- return reject(err)
- }
-
- if (reminder.length > 0) {
- return reject(new Error('Node does not contain the key'))
- }
-
- const prf = {
- blockHash: utils.toBuffer(receipt.blockHash),
- parentNodes: stack.map(s => s.raw),
- root: getRawHeader(block).receiptTrie,
- path: rlp.encode(receipt.transactionIndex),
- value: rlp.decode(rawReceiptNode.value),
- }
- resolve(prf)
- }
- )
- })
-}
-
-export function verifyHeaderProof({ value, valueIndex, headerRoot, proof }) {
- const bufferedValue = utils.toBuffer(value)
- const tree = new MerkleTree([bufferedValue])
- return tree.verify(
- bufferedValue,
- valueIndex,
- utils.toBuffer(headerRoot),
- proof.map(p => utils.toBuffer(p))
- )
-}
-
-export function verifyTxProof(proof) {
- const path = utils.toBuffer(proof.path).toString('hex')
- const value = rlp.decode(utils.toBuffer(proof.value))
- const parentNodes = rlp.decode(utils.toBuffer(proof.parentNodes))
- const txRoot = utils.toBuffer(proof.root)
-
- try {
- var currentNode
- var len = parentNodes.length
- var nodeKey = txRoot
- var pathPtr = 0
- for (var i = 0; i < len; i++) {
- currentNode = parentNodes[i]
- const encodedNode = Buffer.from(
- utils.sha3(rlp.encode(currentNode)),
- 'hex'
- )
- if (!nodeKey.equals(encodedNode)) {
- return false
- }
-
- if (pathPtr > path.length) {
- return false
- }
-
- switch (currentNode.length) {
- case 17: // branch node
- if (pathPtr === path.length) {
- if (currentNode[16] === rlp.encode(value)) {
- return true
- } else {
- return false
- }
- }
- nodeKey = currentNode[parseInt(path[pathPtr], 16)] // must === sha3(rlp.encode(currentNode[path[pathptr]]))
- pathPtr += 1
- break
- case 2:
- pathPtr += nibblesToTraverse(
- currentNode[0].toString('hex'),
- path,
- pathPtr
- )
- if (pathPtr === path.length) {
- // leaf node
- if (currentNode[1].equals(rlp.encode(value))) {
- return true
- } else {
- return false
- }
- } else {
- // extension node
- nodeKey = currentNode[1]
- }
- break
- default:
- return false
- }
- }
- } catch (e) {
- return false
- }
- return false
-}
-
-export function verifyReceiptProof(proof) {
- return verifyTxProof(proof, true)
-}
-
-//
-// Helper methods
-//
-
-// raw header
-function getRawHeader(_block) {
- if (typeof _block.difficulty !== 'string') {
- _block.difficulty = '0x' + _block.difficulty.toString(16)
- }
-
- const block = new EthereumBlock(_block)
- return block.header
-}
-
-// squanch transaction
-export function squanchTx(tx) {
- tx.gasPrice = '0x' + parseInt(tx.gasPrice).toString(16)
- tx.value = '0x' + parseInt(tx.value).toString(16) || '0'
- tx.gas = '0x' + parseInt(tx.gas).toString(16)
- tx.data = tx.input
- return tx
-}
-
-function nibblesToTraverse(encodedPartialPath, path, pathPtr) {
- let partialPath
- if (
- String(encodedPartialPath[0]) === '0' ||
- String(encodedPartialPath[0]) === '2'
- ) {
- partialPath = encodedPartialPath.slice(2)
- } else {
- partialPath = encodedPartialPath.slice(1)
- }
-
- if (partialPath === path.slice(pathPtr, pathPtr + partialPath.length)) {
- return partialPath.length
- } else {
- throw new Error('path was wrong')
- }
-}

MODIFY
src/index.js
src/index.js
@@ -5,16 +5,10 @@ import utils from 'ethereumjs-util'
import queryString from 'query-string'
import {
- getTxBytes,
- getReceiptBytes,
- getTxProof,
- getReceiptProof,
verifyTxProof,
verifyReceiptProof,
verifyHeaderProof,
} from './helpers/proofs'
-import { getHeaders, getBlockHeader } from './helpers/blocks'
-import MerkleTree from './helpers/merkle-tree'
import RootChainArtifacts from '../artifacts/RootChain'
import ChildERC20Artifacts from '../artifacts/ChildERC20'
@@ -587,73 +581,6 @@ export default class Matic {
return this._wrapWeb3Promise(processExits.send(_options), options)
}
- async withdrawLocally(txId, options = {}) {
- const withdrawTx = await this._web3.eth.getTransaction(txId)
- const withdrawReceipt = await this._web3.eth.getTransactionReceipt(txId)
- const withdrawBlock = await this._web3.eth.getBlock(
- withdrawReceipt.blockNumber,
- true
- )
-
- // draft withdraw obj
- const withdrawObj = {
- txId: txId,
- block: withdrawBlock,
- tx: withdrawTx,
- receipt: withdrawReceipt,
- }
-
- const txProof = await getTxProof(withdrawObj.tx, withdrawObj.block)
- const receiptProof = await getReceiptProof(
- withdrawObj.receipt,
- withdrawObj.block,
- this._web3
- )
-
- const currentHeaderBlock = await this._rootChainContract.methods
- .currentHeaderBlock()
- .call()
-
- const header = await this._rootChainContract.methods
- .headerBlock(parseInt(currentHeaderBlock, 10) - 1)
- .call()
-
- const headerNumber = +currentHeaderBlock - 1
- const start = header.start
- const end = header.end
- const headers = await getHeaders(start, end, this._web3)
- const tree = new MerkleTree(headers)
- const headerProof = await tree.getProof(getBlockHeader(withdrawObj.block))
-
- const withdrawTxObject = this._withdrawManagerContract.methods.withdrawBurntTokens(
- headerNumber.toString(), // header block
- utils.bufferToHex(Buffer.concat(headerProof)), // header proof
- withdrawObj.block.number.toString(), // block number
- withdrawObj.block.timestamp.toString(), // block timestamp
- utils.bufferToHex(withdrawObj.block.transactionsRoot.toString()), // tx root
- utils.bufferToHex(withdrawObj.block.receiptsRoot.toString()), // tx root
- utils.bufferToHex(rlp.encode(receiptProof.path)), // key for trie (both tx and receipt)
- utils.bufferToHex(getTxBytes(withdrawObj.tx)), // tx bytes
- utils.bufferToHex(rlp.encode(txProof.parentNodes)), // tx proof nodes
- utils.bufferToHex(getReceiptBytes(withdrawObj.receipt)), // receipt bytes
- utils.bufferToHex(rlp.encode(receiptProof.parentNodes)) // reciept proof nodes
- )
-
- options.data = withdrawTxObject.encodeABI()
-
- const _options = await this._fillOptions(
- options,
- withdrawTxObject,
- this._parentWeb3
- )
-
- if (options.encodeAbi) {
- return _options
- }
-
- return this._wrapWeb3Promise(withdrawTxObject.send(_options), options)
- }
-
sendSignedTransaction(signedTransactionData, options) {
let web3Object = this._web3
if (options.parent) {
@@ -725,9 +652,9 @@ export default class Matic {
])
return {
from,
- gas: gasLimit,
- gasLimit,
- gasPrice,
+ gas: Web3.utils.toHex(gasLimit),
+ gasLimit: Web3.utils.toHex(gasLimit),
+ gasPrice: Web3.utils.toHex(gasPrice),
nonce,
chainId,
value: options.value || 0,

remove withdraw locally method