Skip to content

Commit

Permalink
Merge pull request #71 from nguyenphuminh/fix-serialization
Browse files Browse the repository at this point in the history
Fix serialization
  • Loading branch information
nguyenphuminh authored Jul 4, 2023
2 parents d484661 + 3caa6db commit 9a9f256
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 14 deletions.
2 changes: 1 addition & 1 deletion CONTRACT.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ const transaction = new Transaction("some contract address", amount, gas, {
});
```

Note that all args should be numbers and they will be converted to hex strings in execution.
Note that all args should be strings that either represent a hex string or a decimal number, and they will be converted to hex strings in execution.

## Example

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "jechain",
"version": "0.24.0",
"version": "0.25.0",
"description": "Node for JeChain - an experimental smart contract blockchain network",
"main": "./index.js",
"scripts": {
Expand Down
6 changes: 5 additions & 1 deletion src/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,9 @@
"BLOCK_GAS_LIMIT": "50000000000000",
"INITIAL_SUPPLY": "100000000000000000000000000",
"EMPTY_HASH": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"FIRST_ACCOUNT": "52472d59e3c01bc2cf9496c959d924ce5f469d4e097c395f5605f70633e44a28"
"FIRST_ACCOUNT": "52472d59e3c01bc2cf9496c959d924ce5f469d4e097c395f5605f70633e44a28",
"CONTRACT_FLAG": {
"DEPLOY": 0,
"CALL": 1
}
}
2 changes: 1 addition & 1 deletion src/core/runtime.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ async function jelscript(input, originalState = {}, gas, stateDB, block, txInfo,

const memory = {}, state = { ...originalState }, storage = {};

const userArgs = typeof txInfo.additionalData.txCallArgs !== "undefined" ? txInfo.additionalData.txCallArgs.map(arg => "0x" + arg.toString(16)) : [];
const userArgs = typeof txInfo.additionalData.txCallArgs !== "undefined" ? txInfo.additionalData.txCallArgs.map(arg => "0x" + BigInt(arg).toString(16)) : [];

let ptr = 0;

Expand Down
60 changes: 50 additions & 10 deletions src/core/transaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const { isNumber } = require("../utils/utils");
const crypto = require("crypto"), SHA256 = message => crypto.createHash("sha256").update(message).digest("hex");
const EC = require("elliptic").ec, ec = new EC("secp256k1");

const { EMPTY_HASH } = require("../config.json");
const { EMPTY_HASH, CONTRACT_FLAG } = require("../config.json");

class Transaction {
constructor(recipient = "", amount = "0", gas = "1000000000000", additionalData = {}, nonce = 0) {
Expand Down Expand Up @@ -49,15 +49,39 @@ class Transaction {
tx.signature.v.padStart(2, "0");

// Additional data
txHexString += Buffer.from(JSON.stringify(tx.additionalData), 'utf8').toString('hex');
if (typeof tx.additionalData.scBody === "string") {
let scBodyHex = Buffer.from(tx.additionalData.scBody, "utf8").toString("hex");

if (scBodyHex.length % 2 !== 0) { scBodyHex = "0" + scBodyHex };

txHexString += "00" + scBodyHex;
} else if (typeof tx.additionalData.contractGas === "string") {
txHexString += "01" + BigInt(tx.additionalData.contractGas).toString(16).padStart(22, "0");

if (Array.isArray(tx.additionalData.txCallArgs)) {
for (const arg of tx.additionalData.txCallArgs) {
let newArg = BigInt(arg).toString(16);

if (newArg.length % 2 !== 0) { newArg = "0" + newArg; }

// Offset for knowing arg's size
txHexString += Math.floor(newArg.length / 2).toString(16).padStart(8, "0");

// The arg itself
txHexString += newArg;
}
}
} else {
txHexString += "02";
}

return new Array(...Buffer.from(txHexString, "hex"));
}

static deserialize(tx) {
static deserialize(tx) {
let txHexString = Buffer.from(tx).toString("hex");

const txObj = { signature: {} };
const txObj = { signature: {}, additionalData: {} };

txObj.recipient = txHexString.slice(0, 64);
txHexString = txHexString.slice(64);
Expand All @@ -80,7 +104,27 @@ class Transaction {
txObj.signature.v = txHexString.slice(0, 2);
txHexString = txHexString.slice(2);

txObj.additionalData = JSON.parse(Buffer.from(txHexString, 'hex').toString('utf8'));
const contractFlag = parseInt("0x" + txHexString.slice(0, 2));
txHexString = txHexString.slice(2);

if (contractFlag === CONTRACT_FLAG.DEPLOY) {
txObj.additionalData.scBody = Buffer.from(txHexString, "hex").toString("utf8");
} else if (contractFlag === CONTRACT_FLAG.CALL) {
txObj.additionalData.contractGas = BigInt("0x" + txHexString.slice(0, 22)).toString();
txHexString = txHexString.slice(22);

if (txHexString.length > 0) {
txObj.additionalData.txCallArgs = [];
}

while (txHexString.length > 0) {
const offset = parseInt(txHexString.slice(0, 8), 16);
txHexString = txHexString.slice(8);

txObj.additionalData.txCallArgs.push(BigInt("0x" + txHexString.slice(0, offset * 2)).toString());
txHexString = txHexString.slice(offset * 2);
}
} // Any other flag will make the additional data empty

return txObj;
}
Expand Down Expand Up @@ -125,7 +169,7 @@ class Transaction {
return ec.keyFromPublic(txSenderPubkey).getPublic("hex");
}

static async isValid(tx, stateDB, check) {
static async isValid(tx, stateDB) {
let txSenderPubkey;

// If recovering public key fails, then transaction is not valid.
Expand All @@ -134,8 +178,6 @@ class Transaction {
} catch (e) {
return false;
}

if (tx.additionalData.contractGas && check) console.log(tx);

const txSenderAddress = SHA256(txSenderPubkey);

Expand All @@ -147,8 +189,6 @@ class Transaction {
if (dataFromSender.codeHash !== EMPTY_HASH) return false;
}

if (tx.additionalData.contractGas && check) console.log(tx);

return BigInt(tx.amount) >= 0; // Transaction's amount must be at least 0.

// We don't check balance here, we will check balance directly in execution
Expand Down

0 comments on commit 9a9f256

Please sign in to comment.