Skip to content
This repository has been archived by the owner on Apr 21, 2020. It is now read-only.

Commit

Permalink
Contract creation (#216)
Browse files Browse the repository at this point in the history
* Add interface

* Disable no-null-keyword

Otherways alert  when define object with key = null for the test  https://web3js.readthedocs.io/en/1.0/web3-eth.html?highlight=block#id50

* Add seed data

* Add test for extractTransactionData()

* Don not save to = null for contract creation transaction

Fixes #95

* Add extra check
  • Loading branch information
Mykola authored Mar 12, 2018
1 parent 93f1a66 commit b292890
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 11 deletions.
8 changes: 6 additions & 2 deletions src/common/CommonInterfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export interface ITransactionReceipt {
logs: any[] // TODO add log interface
}

export interface ITransaction {
export interface ISavedTransaction {
_id: string,
addresses: string[],
blockNumber: number,
Expand All @@ -58,7 +58,7 @@ export interface ITransaction {
blockHash: string | null,
blockNumber: number,
from: string,
gas: string,
gas: number,
gasPrice: string,
hash: string,
input: string,
Expand All @@ -71,6 +71,10 @@ export interface ITransaction {
s?: string
}

export interface IExtractedTransaction extends ITransaction {
_id: string
}

export interface IBlock {
difficulty: string,
extraData: string,
Expand Down
16 changes: 8 additions & 8 deletions src/common/TransactionParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ import { TransactionOperation } from "../models/TransactionOperationModel";
import { removeScientificNotationFromNumbString } from "./Utils";
import { Config } from "./Config";
import { Promise } from "bluebird";
import { IDecodedLog, IContract, ITransaction } from "./CommonInterfaces";

import { IDecodedLog, IContract, ITransaction, IBlock, IExtractedTransaction, ISavedTransaction } from "./CommonInterfaces";
const erc20abi = require("./contracts/Erc20Abi");
const erc20ABIDecoder = require("abi-decoder");
erc20ABIDecoder.addABI(erc20abi);
Expand All @@ -23,14 +22,14 @@ export class TransactionParser {
return new Transaction(this.extractTransactionData(block, tx));
});
});
const txIDs = extractedTransactions.map((tx: ITransaction) => tx._id);
const txIDs = extractedTransactions.map((tx: IExtractedTransaction) => tx._id);

return this.fetchTransactionReceipts(txIDs).then((receipts: any) => {
return this.mergeTransactionsAndReceipts(extractedTransactions, receipts);
}).then((transactions: any) => {
const bulkTransactions = Transaction.collection.initializeUnorderedBulkOp();

transactions.forEach((transaction: ITransaction) =>
transactions.forEach((transaction: IExtractedTransaction) =>
bulkTransactions.find({_id: transaction._id}).upsert().replaceOne(transaction)
);

Expand Down Expand Up @@ -68,9 +67,10 @@ export class TransactionParser {
return newTransaction;
}

private extractTransactionData(block: any, transaction: any) {
extractTransactionData(block: IBlock, transaction: ITransaction) {
const from = String(transaction.from).toLowerCase();
const to = String(transaction.to).toLowerCase();
const to: string = transaction.to === null ? "" : String(transaction.to).toLowerCase();
const addresses: string[] = to ? [from, to] : [from];

return {
_id: String(transaction.hash),
Expand All @@ -84,13 +84,13 @@ export class TransactionParser {
gasPrice: String(transaction.gasPrice),
gasUsed: String(0),
input: String(transaction.input),
addresses: [from, to]
addresses
};
}

// ========================== OPERATION PARSING ========================== //

public parseTransactionOperations(transactions: ITransaction[], contracts: IContract[]) {
public parseTransactionOperations(transactions: ISavedTransaction[], contracts: IContract[]) {
if (!transactions || !contracts) return Promise.resolve();

return Promise.map(transactions, (transaction) => {
Expand Down
52 changes: 52 additions & 0 deletions test/SeedData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Contract creation trasaction
export const contractCreateTrx = {
blockHash: "0xcea93534febc780727c1404fba8ef420b728eab17f8ebdea38a1b7b79a941325",
blockNumber: 4925033,
from: "0xb42b20ddbEabdC2a288Be7FF847fF94fB48d2579",
gas: 500000,
gasPrice: "50000000000",
hash: "0x5051473cc1cf2b934fc13e7863bd44b19392eae25f619f3d6653c89e30a55b1a",
input: "0x6060604052341561000c57fe5b5b73209c4784ab1e8183cf58ca33cb740efbf3fc18ef600060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555073b42b20ddbeabdc2a288be7ff847ff94fb48d2579600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5b6104a0806100c86000396000f30060606040523615610055576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063661172761461014857806382c90ac01461017e578063b76ea962146101b4575b6101465b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163460405180905060006040518083038185876187965a03f1925050501561013d577f23919512b2162ddc59b67a65e3b03c419d4105366f7d4a632f5d3c3bee9b1cff600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1610143565b60006000fd5b5b565b005b341561015057fe5b61017c600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610225565b005b341561018657fe5b6101b2600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506102c8565b005b610223600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509190505061036b565b005b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156102825760006000fd5b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5b50565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156103255760006000fd5b80600060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5b50565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156103c85760006000fd5b8173ffffffffffffffffffffffffffffffffffffffff1634826040518082805190602001908083836000831461041d575b80518252602083111561041d576020820191506020810190506020830392506103f9565b505050905090810190601f1680156104495780820380516001836020036101000a031916815260200191505b5091505060006040518083038185876187965a03f192505050151561046e5760006000fd5b5b5b50505600a165627a7a7230582015dd8a30edc4d2b88e51c1e252cdc5a08cd0159c2d5d7b063fdaad85d6e813e40029",
nonce: 285675,
to: null,
transactionIndex: 27,
value: "0",
}

// ETH transfer
export const ethTransferTrx = {
blockHash: "0x946b9020ea3a55980a08bb362fa98e883a8d3b63a3c3d67bcbbb0a0401edde84",
blockNumber: 4902828,
from: "0xdC2C39938b86Ce47d14cF2000Bbc0F3CCA9f09B3",
gas: 21000,
gasPrice: "110000000000",
hash: "0x3c9ece41403d76125352ffd941c8da4f2f379f258f3187987f7fdb28d5bb86db",
input: "0x",
nonce: 2,
to: "0xF08BDf21373A09aB7eDD7769A402D3a22826D317",
transactionIndex: 221,
value: "0",
}

export const block = { difficulty: "1771245602758757",
extraData: "0xe4b883e5bda9e7a59ee4bb99e9b1bc",
gasLimit: 8000000,
gasUsed: 7982114,
hash: "0xdecf0e6886f0adeb4dca839a764d905add7830e703d4758773e7470cf3ee481b",
logsBloom: "0x00002021904001000a82020044000000000010000001000480032410112001680020010081000040801800000820008081010118010900101043020020200000000000418420000120106088a0000000020020000020100000010100000000011010042002400001005040a1000008000200020018144800062080750002220020108010402000000400040900011011001101001600081400001002000880000a0482002200000000000000b105840001000405000080008010501421084021c000840208060800021e000002004020a00020049208000010001040090028000010000104200000000000008901810010000004000000680208801400000090",
miner: "0x829BD824B016326A401d083B33D092293333A830",
mixHash: "0x53d51eb64e82632658c50a0ac02ba44ce78ff5ebe16311cde2df3b9d372b0564",
nonce: "0xee7660201fde3240",
number: 4748244,
parentHash: "0xcf6dd8d1ff207cd937e6b0e30a0d2ec462129d495c4edf5dcf7ee0d3567ae55b",
receiptsRoot: "0x712b97042663d98abed51210814d9fab7a08f92e7bf6b2902c6f123679a452e3",
sha3Uncles: "0x2d8f607dd5d66ee3003975eecb3e0fe2278ddb84b2a20beb6699eddb8d596c19",
size: 35246,
stateRoot: "0x0e397fa8b0ede6defebb5cbea187fb6a099a625e80101bc5dc3f0c659cfdbae4",
timestamp: 1513510292,
totalDifficulty: "1761498747834301809225",
transactions: [],
transactionsRoot: "0x5555292fb1f08aa06b65725117a88a00cde2dbfb73fd9939890a5bd6910f1fa4",
uncles: ["0x7904fd964c65e5e62cd894a947f7775eb8fdd90f46c4519ae8ee2af006e13dac"]
}

35 changes: 35 additions & 0 deletions test/TransactionParser.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@

import { TransactionParser } from "../src/common/TransactionParser";
import * as mocha from "mocha";
import { block, contractCreateTrx, ethTransferTrx } from "./SeedData";
import { should, expect } from "chai"


describe("Test TransactionParser", () => {
describe("Test extractTransactionData()", () => {
const extractTransactionData = new TransactionParser().extractTransactionData;
it("Should extract transaction data", () => {
const transaction = extractTransactionData(block, ethTransferTrx);

transaction.should.to.have.property("_id").to.be.a("string");
transaction.should.to.have.property("blockNumber").to.be.a("number");
transaction.should.to.have.property("timeStamp").to.be.a("string");
transaction.should.to.have.property("nonce").to.be.a("number");
transaction.should.to.have.property("from").to.be.a("string");
transaction.should.to.have.property("to").to.be.a("string");
transaction.should.to.have.property("value").to.be.a("string");
transaction.should.to.have.property("gas").to.be.a("string");
transaction.should.to.have.property("gasPrice").to.be.a("string");
transaction.should.to.have.property("gasUsed").to.be.a("string");
transaction.should.to.have.property("input").to.be.a("string");
transaction.should.to.have.property("addresses").to.be.a("array").to.have.lengthOf(2);
})

it("Should extract contract creation transaction correctly", () => {
const transaction = extractTransactionData(block, contractCreateTrx);

expect(transaction.to).to.equal("");
expect(transaction.addresses).to.have.lengthOf(1);
})
})
})
2 changes: 1 addition & 1 deletion tslint.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
],
"no-internal-module": true,
"no-trailing-whitespace": true,
"no-null-keyword": true,
"no-null-keyword": false,
"prefer-const": true,
"jsdoc-format": true
}
Expand Down

0 comments on commit b292890

Please sign in to comment.