Skip to content

Instantly share code, notes, and snippets.

@visvirial
Created September 12, 2019 23:57
Show Gist options
  • Save visvirial/e72227d8a09171856b143f3df22ea015 to your computer and use it in GitHub Desktop.
Save visvirial/e72227d8a09171856b143f3df22ea015 to your computer and use it in GitHub Desktop.
const crypto = require('crypto');
const grpc = require('grpc');
const protoLoader = require('@grpc/proto-loader');
const protobufjs = require('protobufjs');
const ed25519 = require('ed25519');
const PROTO_DIR = __dirname + '/proto';
const privateKey = Buffer.from('fbcedfd8848bf097ca79a8248a26d929ebf7104c1fcc471a6c4fd87113798766', 'hex');
// SHA3-256 hash of an input.
const hash = (data) => {
const h = crypto.createHash('sha3-256');
h.update(data);
return h.digest();
};
const getAddress = (publicKey) => {
return hash(publicKey);
}
const getGRpcClient = () => {
const packageDefinition = protoLoader.loadSync(
PROTO_DIR + '/admission_control.proto',
{
keepCase: true,
longs: Number,
enums: String,
defaults: true,
bytes: String,
oneofs: true,
}
);
const protoDescriptor = grpc.loadPackageDefinition(packageDefinition);
return new protoDescriptor.admission_control.AdmissionControl('ac.testnet.libra.org:8000', grpc.credentials.createInsecure());
};
// Get peer-to-peer transfer transaction object.
const getTransferTransaction = (seq, sender, sendTo, sendAmount) => {
const amount = Buffer.alloc(8);
amount.writeUIntLE(sendAmount, 0, 6);
return {
senderAccount: sender,
sequenceNumber: seq,
script: {
code: Buffer.from([76,73,66,82,65,86,77,10,1,0,7,1,74,0,0,0,4,0,0,0,3,78,0,0,0,6,0,0,0,12,84,0,0,0,6,0,0,0,13,90,0,0,0,6,0,0,0,5,96,0,0,0,41,0,0,0,4,137,0,0,0,32,0,0,0,7,169,0,0,0,15,0,0,0,0,0,0,1,0,2,0,1,3,0,2,0,2,4,2,0,3,0,3,2,4,2,6,60,83,69,76,70,62,12,76,105,98,114,97,65,99,99,111,117,110,116,4,109,97,105,110,15,112,97,121,95,102,114,111,109,95,115,101,110,100,101,114,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,2,1,4,0,12,0,12,1,19,1,0,2]),
arguments: [
{
type: 1, // ADDRESS
data: sendTo,
},
{
type: 0, // U64
data: amount,
}
],
},
maxGasAmount: 140000,
gasUnitPrice: 0,
expirationTime: Math.floor(new Date().getTime() / 1000) + 120,
};
};
const getSignature = (rawTx, privateKey) => {
return ed25519.Sign(hash(Buffer.concat([hash(Buffer.from('RawTransaction@@$$LIBRA$$@@', 'utf8')), rawTx])), privateKey);
};
const main = async () => {
const keyPair = ed25519.MakeKeypair(privateKey);
const address = getAddress(keyPair.publicKey);
console.log(`Private key: ${privateKey.toString('hex')}`);
console.log(`Public Key: ${keyPair.publicKey.toString('hex')}`);
console.log(`Address: ${address.toString('hex')}`);
const tx = getTransferTransaction(
0, // sequence
address, // sender
Buffer.from('ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', 'hex'), // receiver
12345 // amount
);
console.log(tx);
const RawTransaction = (await protobufjs.load(PROTO_DIR + '/transaction.proto')).lookupType('types.RawTransaction');
const rawTx = RawTransaction.encode(RawTransaction.create(tx)).finish();
const signature = getSignature(rawTx, privateKey);
console.log(`Signature: ${signature.toString('hex')}`);
getGRpcClient().submitTransaction({
signed_txn: {
raw_txn_bytes: rawTx,
sender_public_key: keyPair.publicKey,
sender_signature: signature,
}
}, (error, response) => {
if(error) throw error;
console.log(response);
});
};
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment