mirror of
https://github.com/jackyzha0/quartz.git
synced 2025-12-24 13:24:05 -06:00
57 lines
1.9 KiB
JavaScript
57 lines
1.9 KiB
JavaScript
// type Var = {
|
|
// name: String
|
|
// type: "uint256" | "bytes32" | ...
|
|
// }
|
|
//
|
|
// type Method = {
|
|
// name: String
|
|
// inputs: [Var]
|
|
// output: [Var]
|
|
// constant: Bool
|
|
// payable: Bool
|
|
// }
|
|
|
|
const Bytes = require("./bytes");
|
|
const Nat = require("./nat");
|
|
const keccak256s = require("./hash").keccak256s;
|
|
|
|
// (type : String), JSType(type) -> {data: Bytes, dynamic: Bool}
|
|
// ABI-encodes a single term.
|
|
const encode = (type, value) => {
|
|
if (type === "bytes") {
|
|
const length = Bytes.length(value);
|
|
const nextMul32 = (((length - 1) / 32 | 0) + 1) * 32;
|
|
const lengthEncoded = encode("uint256", Nat.fromNumber(length)).data;
|
|
const bytesEncoded = Bytes.padRight(nextMul32, value);
|
|
return { data: Bytes.concat(lengthEncoded, bytesEncoded), dynamic: true };
|
|
} else if (type === "uint256" || type === "bytes32" || type === "address") {
|
|
return { data: Bytes.pad(32, value), dynamic: false };
|
|
} else {
|
|
throw "Eth-lib can't encode ABI type " + type + " yet.";
|
|
}
|
|
};
|
|
|
|
// (method : Method), [JSType(method.inputs[i].type)] -> Bytes
|
|
// ABI-encodes the transaction data to call a method.
|
|
const methodData = (method, params) => {
|
|
const methodSig = method.name + "(" + method.inputs.map(i => i.type).join(",") + ")";
|
|
const methodHash = keccak256s(methodSig).slice(0, 10);
|
|
let encodedParams = params.map((param, i) => encode(method.inputs[i].type, param));
|
|
var headBlock = "0x";
|
|
let dataBlock = "0x";
|
|
for (var i = 0; i < encodedParams.length; ++i) {
|
|
if (encodedParams[i].dynamic) {
|
|
var dataLoc = encodedParams.length * 32 + Bytes.length(dataBlock);
|
|
headBlock = Bytes.concat(headBlock, Bytes.pad(32, Nat.fromNumber(dataLoc)));
|
|
dataBlock = Bytes.concat(dataBlock, encodedParams[i].data);
|
|
} else {
|
|
headBlock = Bytes.concat(headBlock, encodedParams[i].data);
|
|
}
|
|
}
|
|
return Bytes.flatten([methodHash, headBlock, dataBlock]);
|
|
};
|
|
|
|
module.exports = {
|
|
encode,
|
|
methodData
|
|
}; |