Skip to content

Commit

Permalink
docs(guides): Update multisig guide (#374)
Browse files Browse the repository at this point in the history
Move guide from adv to basic and generate it from example script
  • Loading branch information
snowypowers authored Dec 5, 2018
1 parent 408326b commit f6b4c73
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 135 deletions.
119 changes: 0 additions & 119 deletions docs/guides/adv/multisig.md

This file was deleted.

111 changes: 111 additions & 0 deletions docs/guides/basic/multi.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
---
id: multi
title: Basic - Signing with a multi-sig account
---

This tutorial aims to show how to sign with a multi-sig account. This will be done by sending some assets from a multi-sig account.

A multi-sig Account can be identified by its verification script. It uses the `CHECKMULTISIG` OpCode (`ae` in hexstring). Thus, if you see any verification scripts ending with `ae`, it is likely to be a multi-sig Account.

## Setup
Here I will assume that you have already sent some assets over to the multi-sig account.

```js
const { default: Neon, api, wallet, tx, rpc } = require("@cityofzion/neon-js");

const neoscan = new api.neoscan.instance(
"https://neoscan-testnet.io/api/main_net"
);
const rpcNodeUrl = "http://seed2.neo.org:20332";
```

Our multi-sig account in this example is made up of 3 keys with a signing threshold of 2.
Do note that the order of keys in the array matters. A different order will generate a totally different address.


```js
const keyA = new wallet.Account(
"7d128a6d096f0c14c3a25a2b0c41cf79661bfcb4a8cc95aaaea28bde4d732344"
);
const keyB = new wallet.Account(
"9ab7e154840daca3a2efadaf0df93cd3a5b51768c632f5433f86909d9b994a69"
);
const keyC = new wallet.Account(
"3edee7036b8fd9cef91de47386b191dd76db2888a553e7736bb02808932a915b"
);

const multisigAcct = wallet.Account.createMultiSig(2, [
keyA.publicKey,
keyB.publicKey,
keyC.publicKey
]);

console.log("\n\n--- Multi-sig ---");
console.log(`My multi-sig address is ${multisigAcct.address}`);
console.log(`My multi-sig verificationScript is ${multisigAcct.contract.script}`);
```

## Construct Transaction
Similar to how we setup a transaction for a normal account transfer, we also do the same for our transfer from a multi-sig account.


```js
var constructTx = neoscan.getBalance(multisigAcct.address).then(balance => {
const transaction = Neon.create
.contractTx()
.addIntent("NEO", 1, keyA.address)
.addIntent("GAS", 0.00000001, keyB.address)
.calculate(balance);

return transaction;
});
```

## Sign Transaction
The only difference is in the signing of transactions. We need to sign the transaction individually by each key first. Then, we combine the signatures together to form a multi-sig witness. We should only see 1 witness attached to the transaction.


```js
const signTx = constructTx.then(transaction => {
const txHex = transaction.serialize(false);

// This can be any 2 out of the 3 keys.
const sig1 = wallet.sign(txHex, keyB.privateKey);
const sig2 = wallet.sign(txHex, keyC.privateKey);

const multiSigWitness = tx.Witness.buildMultiSig(
txHex,
[sig1, sig2],
multisigAcct
);

transaction.addWitness(multiSigWitness);

console.log("\n\n--- Transaction ---");
console.log(JSON.stringify(transaction.export(), undefined, 2));

console.log("\n\n--- Transaction hash---");
console.log(transaction.hash)

console.log("\n\n--- Transaction string ---")
console.log(transaction.serialize(true));
return transaction;
});
```

## Send Transaction
We send off the transaction using sendrawtransaction RPC call like any other normal transaction.


```js
const sendTx = signTx
.then(transaction => {
const client = new rpc.RPCClient(rpcNodeUrl);
return client.sendRawTransaction(transaction.serialize(true));
})
.then(res => {
console.log("\n\n--- Response ---");
console.log(res);
})
.catch(err => console.log(err));
```
31 changes: 22 additions & 9 deletions examples/basic/multi.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
/**
---
id: multisig-signing
title: Signing with a multi-sig account
id: multi
title: Basic - Signing with a multi-sig account
---
This tutorial aims to show how to sign with a multi-sig account. This will be done by sending some assets from a multi-sig account.
A multi-sig Account can be identified by its verification script. It uses the `CHECKMULTISIG` OpCode (`ae` in hexstring). Thus, if you see any verification scripts ending with `ae`, it is likely to be a multi-sig Account.
## Setup
Here I will assume that you have already sent some assets over to the multi-sig account.
*/


const { api, wallet, tx, rpc } = require("@cityofzion/neon-js");
const Neon = require("@cityofzion/neon-js").default;
const { default: Neon, api, wallet, tx, rpc } = require("@cityofzion/neon-js");

const neoscan = new api.neoscan.instance(
"https://neoscan-testnet.io/api/main_net"
);
const rpcNodeUrl = "http://seed5.neo.org:20332";
const rpcNodeUrl = "http://seed2.neo.org:20332";

/**
Our multi-sig account in this example is made up of 3 keys with a signing threshold of 2.
Expand All @@ -39,8 +39,9 @@ const multisigAcct = wallet.Account.createMultiSig(2, [
keyC.publicKey
]);

console.log("\n\n--- Multi-sig ---");
console.log(`My multi-sig address is ${multisigAcct.address}`);
console.log(`My multi-sig verificationScript is ${multisigAcct.contract}`);
console.log(`My multi-sig verificationScript is ${multisigAcct.contract.script}`);

/**
## Construct Transaction
Expand All @@ -50,8 +51,10 @@ var constructTx = neoscan.getBalance(multisigAcct.address).then(balance => {
const transaction = Neon.create
.contractTx()
.addIntent("NEO", 1, keyA.address)
.addIntent("GAS", 0.00001, keyB.address)
.addIntent("GAS", 0.00000001, keyB.address)
.calculate(balance);

return transaction;
});

/**
Expand All @@ -72,6 +75,15 @@ const signTx = constructTx.then(transaction => {
);

transaction.addWitness(multiSigWitness);

console.log("\n\n--- Transaction ---");
console.log(JSON.stringify(transaction.export(), undefined, 2));

console.log("\n\n--- Transaction hash---");
console.log(transaction.hash)

console.log("\n\n--- Transaction string ---")
console.log(transaction.serialize(true));
return transaction;
});

Expand All @@ -85,6 +97,7 @@ const sendTx = signTx
return client.sendRawTransaction(transaction.serialize(true));
})
.then(res => {
console.log(res.result);
console.log("\n\n--- Response ---");
console.log(res);
})
.catch(err => console.log(err));
2 changes: 1 addition & 1 deletion examples/basic/sendasset.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const { default: Neon, api, wallet } = require("@cityofzion/neon-js");

const sendingKey =
"9ab7e154840daca3a2efadaf0df93cd3a5b51768c632f5433f86909d9b994a69";
const receivingAddress = "ALq7AWrhAueN6mJNqk6FHJjnsEoPRytLdW";
const receivingAddress = "ASo1RcNVLiV3yQ8j3ZyZv5EWfqBBT8s2Yd";
const network = "TestNet";

/**
Expand Down
8 changes: 4 additions & 4 deletions website/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,6 @@
"guides/adv/apicore": {
"title": "Advanced - API Core Components"
},
"guides/adv/multisig": {
"title": "Advanced - Working with multi-sig contracts"
},
"guides/adv/multitx": {
"title": "Advanced - Sending multiple transactions in a block"
},
Expand All @@ -71,9 +68,12 @@
"guides/basic/createscript": {
"title": "Basic - Create Smart Contract Script"
},
"guides/basic/invoke": {
"guides/basic/doinvoke": {
"title": "Basic - Invoking a Smart Contract"
},
"guides/basic/multi": {
"title": "Signing with a multi-sig account"
},
"guides/basic/privnet": {
"title": "Basic - Using a Private Net"
},
Expand Down
4 changes: 2 additions & 2 deletions website/sidebars.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
"guides/basic/createscript",
"guides/basic/doinvoke",
"guides/basic/privnet",
"guides/basic/multi",
"guides/adv/multitx",
"guides/adv/apicore",
"guides/adv/multisig"
"guides/adv/apicore"
]
},
"api": {
Expand Down

0 comments on commit f6b4c73

Please sign in to comment.