-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtxByCustSign.ts
73 lines (62 loc) · 3.1 KB
/
txByCustSign.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import { ApiPromise,WsProvider } from "@polkadot/api";
import * as polka_util from "@polkadot/util";
import { Keyring } from "@polkadot/keyring";
import { KeyringPair } from "@polkadot/keyring/types";
import { blake2AsHex,decodeAddress } from '@polkadot/util-crypto';
import { cryptoWaitReady, mnemonicGenerate } from '@polkadot/util-crypto';
import { u8aToHex } from '@polkadot/util';
/*
the code can refer to https://github.com/polkadot-js/api/issues/1421
and it will not work by the refer code. i change the sign detail code
*/
async function main(){
await cryptoWaitReady(); // wait sr25519 init finish
const wsProvider = new WsProvider('wss://westend-rpc.polkadot.io'); // wss://rococo-rpc.polkadot.io
const api = await ApiPromise.create({ provider: wsProvider });
console.log("start handle");
let keyring= new Keyring({
type:"sr25519",
});
const Alice = keyring.addFromUri("//Alice"); // get default develop account
let from = Alice.address;
let to = "5H2Dq1m8Cg7qsMaADCxnPDf3mk3CePDiVdVF6nyNeRbKWjc3";
let amount = BigInt(12345);
const tx = api.tx.balances.transfer(to, amount);
const accountInfo = await api.query.system.account(from) ;
console.log(`nonce:${JSON.stringify( accountInfo)}`)
let signedBlock = await api.rpc.chain.getBlock();
// create the payload
// the blockHash field must be genesisHash.if not the sign will error. i don't know the reason
const signer = api.createType('SignerPayload', {
blockHash: api.genesisHash.toString(),
genesisHash: api.genesisHash.toString(),
nonce:accountInfo.nonce,
runtimeVersion: api.runtimeVersion,
address:from,
method: tx,
version: api.extrinsicVersion,
});
try {
// the below code do not work.
//const { signature } = api.createType('ExtrinsicPayload', signer.toPayload(), { version: api.extrinsicVersion }).sign(Alice);
//console.log(`sign:${signature}`)
// refer to https://github.com/polkadot-js/tools/issues/175
// For the Substrate signatures (MultiSiginature type) it is always 65/66 bytes in length. The first byte is always 00, 01 or 02, (00 = ed25519, 01 = sr25519, 02 = ecdsa), the reaming bytes contain the actual signature data. (64 following for sr/ed, 65 for ecdsa)
let unsignedDetail = signer.toRaw();
const hashed = (unsignedDetail.data.length > (256 + 1) * 2)
? blake2AsHex(unsignedDetail.data)
: unsignedDetail.data;
console.log(`address ${Alice.address} unsigned:${hashed}`)
let sigVal = Alice.sign(hashed);
let newVal = new Uint8Array(sigVal.byteLength+1)
newVal[0] = 0x1; // i use sr25519.so the first byte is 1.it refer to https://github.com/polkadot-js/api/blob/master/packages/types/src/interfaces/extrinsics/definitions.ts#L31
newVal.set(sigVal,1);
console.log("sign:", u8aToHex(newVal))
tx.addSignature(from, newVal, signer.toPayload());
let returnedSign = await tx.send();
console.log(`returned hash:${returnedSign.toString()}`);
} catch (error) {
console.error(error);
}
}
main().catch(console.error).finally(() => process.exit());