From d332207faac13e06a67725f91cc34dc1ed5d8298 Mon Sep 17 00:00:00 2001 From: Zach Ramsay Date: Thu, 10 Aug 2017 13:04:53 -0400 Subject: [PATCH 1/3] docs: roles and multi sig --- docs/guide/roles-and-multi-sig.md | 261 ++++++++++++++++++++++++++++++ 1 file changed, 261 insertions(+) create mode 100644 docs/guide/roles-and-multi-sig.md diff --git a/docs/guide/roles-and-multi-sig.md b/docs/guide/roles-and-multi-sig.md new file mode 100644 index 000000000..c70234906 --- /dev/null +++ b/docs/guide/roles-and-multi-sig.md @@ -0,0 +1,261 @@ +This guide uses the roles functionality provided by `basecli` to create a multi-sig wallet. It builds upon the basecoin basics and key management guides. You should have `basecoin` started with blocks streaming in, and three accounts: `rich, poor, igor` where `rich` was the account used on `basecoin init`, _and_ run `basecli init` with the appropriate flags. Review the intro guides for more information. + +In this example, `rich` will create the role and send it some coins (i.e., fill the multi-sig wallet). Then, `poor` will prepare a transaction to withdraw coins, which will be approved by `igor`. Let's look at our keys: + +``` +basecli keys list +``` + +``` +All keys: +igor 5E4CB7A4E729BA0A8B18DE99E21409B6D706D0F1 +poor 65D406E028319289A0706E294F3B764F44EBA3CF +rich CB76F4092D1B13475272B36585EBD15D22A2848D +``` + +Using the `basecli query account` command, you'll see that `rich` has plenty of coins: + +``` +{ + "height": 81, + "data": { + "coins": [ + { + "denom": "mycoin", + "amount": 9007199254740992 + } + ], + "credit": [] + } +} +``` + +whereas `poor` and `igor` have no coins (in fact, the chain doesn't know about them yet): + +``` +ERROR: Account bytes are empty for address 65D406E028319289A0706E294F3B764F44EBA3CF +``` + +## Create Role + +This first step defines the parameters of a new role, which will have control of any coins sent to it, and only release them if correct conditions are met. In this example, we are going to make a 2/3 multi-sig wallet. Let's look a the command and dissect it below: + +``` +basecli tx create-role --role="10CAFE4E" --min-sigs=2 --members=5E4CB7A4E729BA0A8B18DE99E21409B6D706D0F1,65D406E028319289A0706E294F3B764F44EBA3CF,CB76F4092D1B13475272B36585EBD15D22A2848D --sequence=1 --name=rich +``` + +In the first part we are sending a transaction that creates a role, rather than transfering coins. The `--role` flag is the name of the role (in hex only) and must be in double quotes. The `--min-sigs` and `--members` define your multi-sig parameters. Here, we require a minimum of 2 signatures out of 3 members but we could easily say 3 of 5 or 9 of 10, or whatever your application requires. The `--members` flag requires a comma-seperated list of addresses that will be signatories on the role. Then we set the `--sequence` number for the transaction, which will start at 1 and must be incremented by 1 for every transaction from an account. Finally, we use the name of the key/account that will be used to create the role, in this case the account `rich`. + +Remember that `rich`'s address was used on `basecoin init` and is included in the `--members` list. The command above will prompt for a password (which can also be piped into the command if desired) then - if executed correctly - return some data: + +``` +{ + "check_tx": { + "code": 0, + "data": "", + "log": "" + }, + "deliver_tx": { + "code": 0, + "data": "", + "log": "" + }, + "hash": "4849DA762E19CE599460B9882DD42C7F19655DC1", + "height": 321 +} +``` +showing the block height at which the transaction was committed and its hash. A quick review of what we did: 1) created a role, essentially an account, that requires a minimum of two (2) signatures from three (3) accounts (members). And since it was the account named `rich`'s first transaction, the sequence was set to 1. + +Let's look at the balance of the role that we've created: + +``` +basecli query account role:"10CAFE4E" +``` + +and it should be empty: + +``` +ERROR: Account bytes are empty for address role:10CAFE4E +``` + +Next, we want to send coins _to_ that role. Notice that because this is the second transaction being sent by rich, we need to increase `--sequence` to `2`: + +``` +basecli tx send --fee=90mycoin --amount=10000mycoin --to=role:"10CAFE4E" --sequence=2 --name=rich +``` + +We need to pay a transaction fee to the validators, in this case 90 `mycoin` to send 10000 `mycoin` Notice that for the `--to` flag, to specify that we are sending to a role instead of an account, the `role:` prefix is added before the role. Because it's `rich`'s second transaction, we've incremented the sequence. The output will be nearly identical to the output from `create-role` above. + +Now the role has coins (think of it like a bank). + +Double check with: + +``` +basecli query account role:"10CAFE4E" +``` + +and this time you'll see the coins in the role's account: + +``` +{ + "height": 2453, + "data": { + "coins": [ + { + "denom": "mycoin", + "amount": 10000 + } + ], + "credit": [] + } +} +``` + +`Poor` decides to initiate a multi-sig transaction to himself from the role's account. First, it must be prepared like so: + +``` +basecli tx send --amount=6000mycoin --from=role:"10CAFE4E" --to=65D406E028319289A0706E294F3B764F44EBA3CF --sequence=1 --assume-role="10CAFE4E" --name=poor --multi --prepare=tx.json +``` + +you'll be prompted for `poor`'s password and there won't be any `stdout` to the terminal. Note that the address in the `--to` flag matches the address of `poor`'s account from the beginning of the tutorial. The main output is the `tx.json` file that has just been created. In the above command, the `--assume-role` flag is used to (not clear, since we have --from), while the `--multi` flag is used in combination with `--prepare`, to specify the file that is prepared for a multi-sig transaction. + +The `tx.json` file will look like this: + +``` +{ + "type": "sigs/multi", + "data": { + "tx": { + "type": "chain/tx", + "data": { + "chain_id": "test_chain_id", + "expires_at": 0, + "tx": { + "type": "nonce", + "data": { + "sequence": 1, + "signers": [ + { + "chain": "", + "app": "sigs", + "addr": "65D406E028319289A0706E294F3B764F44EBA3CF" + } + ], + "tx": { + "type": "role/assume", + "data": { + "role": "10CAFE4E", + "tx": { + "type": "coin/send", + "data": { + "inputs": [ + { + "address": { + "chain": "", + "app": "role", + "addr": "10CAFE4E" + }, + "coins": [ + { + "denom": "mycoin", + "amount": 6000 + } + ] + } + ], + "outputs": [ + { + "address": { + "chain": "", + "app": "sigs", + "addr": "65D406E028319289A0706E294F3B764F44EBA3CF" + }, + "coins": [ + { + "denom": "mycoin", + "amount": 6000 + } + ] + } + ] + } + } + } + } + } + } + } + }, + "signatures": [ + { + "Sig": { + "type": "ed25519", + "data": "A38F73BF2D109015E4B0B6782C84875292D5FAA75F0E3362C9BD29B16CB15D57FDF0553205E7A33C740319397A434B7C31CBB10BE7F8270C9984C5567D2DC002" + }, + "Pubkey": { + "type": "ed25519", + "data": "6ED38C7453148DD90DFC41D9339CE45BEFA5EB505FD7E93D85E71DFFDAFD9B8F" + } + } + ] + } +} +``` + +and it is loaded by the next command. + +With the transaction prepared, but not sent, we'll have `igor` sign and send the prepared transaction: + +``` +basecli tx --in=tx.json --name=igor +``` + +which will give output similar to: + +``` +{ + "check_tx": { + "code": 0, + "data": "", + "log": "" + }, + "deliver_tx": { + "code": 0, + "data": "", + "log": "" + }, + "hash": "E345BDDED9517EB2CAAF5E30AFF3AB38A1172833", + "height": 2673 +} +``` + +and voila! That's the basics for creating roles and sending multi-sig transactions. For 3 of 3, you'd repeat the last step for rich as well (recall that poor initiated the multi-sig transaction). We can check the balance of the role: + +``` +basecli query account role:"10CAFE4E" +``` + +and get the result: + +``` +{ + "height": 2683, + "data": { + "coins": [ + { + "denom": "mycoin", + "amount": 4000 + } + ], + "credit": [] + } +} +``` + +and see that `poor` now has 6000 `mycoin`: + +``` +basecli query account 65D406E028319289A0706E294F3B764F44EBA3CF +``` + +to confirm that everything worked as expected. From 4e62c3a1c4f9ba01e527de1e2b008d47c83b2987 Mon Sep 17 00:00:00 2001 From: Zach Ramsay Date: Fri, 18 Aug 2017 15:55:44 -0400 Subject: [PATCH 2/3] docs: no quotes needed for role --- docs/guide/roles-and-multi-sig.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/guide/roles-and-multi-sig.md b/docs/guide/roles-and-multi-sig.md index c70234906..df96c8921 100644 --- a/docs/guide/roles-and-multi-sig.md +++ b/docs/guide/roles-and-multi-sig.md @@ -41,7 +41,7 @@ ERROR: Account bytes are empty for address 65D406E028319289A0706E294F3B764F44EBA This first step defines the parameters of a new role, which will have control of any coins sent to it, and only release them if correct conditions are met. In this example, we are going to make a 2/3 multi-sig wallet. Let's look a the command and dissect it below: ``` -basecli tx create-role --role="10CAFE4E" --min-sigs=2 --members=5E4CB7A4E729BA0A8B18DE99E21409B6D706D0F1,65D406E028319289A0706E294F3B764F44EBA3CF,CB76F4092D1B13475272B36585EBD15D22A2848D --sequence=1 --name=rich +basecli tx create-role --role=10CAFE4E --min-sigs=2 --members=5E4CB7A4E729BA0A8B18DE99E21409B6D706D0F1,65D406E028319289A0706E294F3B764F44EBA3CF,CB76F4092D1B13475272B36585EBD15D22A2848D --sequence=1 --name=rich ``` In the first part we are sending a transaction that creates a role, rather than transfering coins. The `--role` flag is the name of the role (in hex only) and must be in double quotes. The `--min-sigs` and `--members` define your multi-sig parameters. Here, we require a minimum of 2 signatures out of 3 members but we could easily say 3 of 5 or 9 of 10, or whatever your application requires. The `--members` flag requires a comma-seperated list of addresses that will be signatories on the role. Then we set the `--sequence` number for the transaction, which will start at 1 and must be incremented by 1 for every transaction from an account. Finally, we use the name of the key/account that will be used to create the role, in this case the account `rich`. @@ -69,7 +69,7 @@ showing the block height at which the transaction was committed and its hash. A Let's look at the balance of the role that we've created: ``` -basecli query account role:"10CAFE4E" +basecli query account role:10CAFE4E ``` and it should be empty: @@ -81,7 +81,7 @@ ERROR: Account bytes are empty for address role:10CAFE4E Next, we want to send coins _to_ that role. Notice that because this is the second transaction being sent by rich, we need to increase `--sequence` to `2`: ``` -basecli tx send --fee=90mycoin --amount=10000mycoin --to=role:"10CAFE4E" --sequence=2 --name=rich +basecli tx send --fee=90mycoin --amount=10000mycoin --to=role:10CAFE4E --sequence=2 --name=rich ``` We need to pay a transaction fee to the validators, in this case 90 `mycoin` to send 10000 `mycoin` Notice that for the `--to` flag, to specify that we are sending to a role instead of an account, the `role:` prefix is added before the role. Because it's `rich`'s second transaction, we've incremented the sequence. The output will be nearly identical to the output from `create-role` above. @@ -91,7 +91,7 @@ Now the role has coins (think of it like a bank). Double check with: ``` -basecli query account role:"10CAFE4E" +basecli query account role:10CAFE4E ``` and this time you'll see the coins in the role's account: @@ -114,7 +114,7 @@ and this time you'll see the coins in the role's account: `Poor` decides to initiate a multi-sig transaction to himself from the role's account. First, it must be prepared like so: ``` -basecli tx send --amount=6000mycoin --from=role:"10CAFE4E" --to=65D406E028319289A0706E294F3B764F44EBA3CF --sequence=1 --assume-role="10CAFE4E" --name=poor --multi --prepare=tx.json +basecli tx send --amount=6000mycoin --from=role:10CAFE4E --to=65D406E028319289A0706E294F3B764F44EBA3CF --sequence=1 --assume-role=10CAFE4E --name=poor --multi --prepare=tx.json ``` you'll be prompted for `poor`'s password and there won't be any `stdout` to the terminal. Note that the address in the `--to` flag matches the address of `poor`'s account from the beginning of the tutorial. The main output is the `tx.json` file that has just been created. In the above command, the `--assume-role` flag is used to (not clear, since we have --from), while the `--multi` flag is used in combination with `--prepare`, to specify the file that is prepared for a multi-sig transaction. @@ -232,7 +232,7 @@ which will give output similar to: and voila! That's the basics for creating roles and sending multi-sig transactions. For 3 of 3, you'd repeat the last step for rich as well (recall that poor initiated the multi-sig transaction). We can check the balance of the role: ``` -basecli query account role:"10CAFE4E" +basecli query account role:10CAFE4E ``` and get the result: From 4c8bddb02ab03cc726212603f7d08ef76db9c8d3 Mon Sep 17 00:00:00 2001 From: Zach Ramsay Date: Fri, 18 Aug 2017 16:08:27 -0400 Subject: [PATCH 3/3] docs: roles PR fixes --- docs/guide/roles-and-multi-sig.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/docs/guide/roles-and-multi-sig.md b/docs/guide/roles-and-multi-sig.md index df96c8921..665c66062 100644 --- a/docs/guide/roles-and-multi-sig.md +++ b/docs/guide/roles-and-multi-sig.md @@ -117,7 +117,7 @@ and this time you'll see the coins in the role's account: basecli tx send --amount=6000mycoin --from=role:10CAFE4E --to=65D406E028319289A0706E294F3B764F44EBA3CF --sequence=1 --assume-role=10CAFE4E --name=poor --multi --prepare=tx.json ``` -you'll be prompted for `poor`'s password and there won't be any `stdout` to the terminal. Note that the address in the `--to` flag matches the address of `poor`'s account from the beginning of the tutorial. The main output is the `tx.json` file that has just been created. In the above command, the `--assume-role` flag is used to (not clear, since we have --from), while the `--multi` flag is used in combination with `--prepare`, to specify the file that is prepared for a multi-sig transaction. +you'll be prompted for `poor`'s password and there won't be any `stdout` to the terminal. Note that the address in the `--to` flag matches the address of `poor`'s account from the beginning of the tutorial. The main output is the `tx.json` file that has just been created. In the above command, the `--assume-role` flag is used to evaluate account permissions on the transaction, while the `--multi` flag is used in combination with `--prepare`, to specify the file that is prepared for a multi-sig transaction. The `tx.json` file will look like this: @@ -229,7 +229,15 @@ which will give output similar to: } ``` -and voila! That's the basics for creating roles and sending multi-sig transactions. For 3 of 3, you'd repeat the last step for rich as well (recall that poor initiated the multi-sig transaction). We can check the balance of the role: +and voila! That's the basics for creating roles and sending multi-sig transactions. For 3 of 3, you'd add an intermediate transactions like: + +``` +basecli tx --in=tx.json --name=igor --prepare=tx2.json +``` + +before having rich sign and send the transaction. The `--prepare` flag writes files to disk rather than sending the transaction and can be used to chain together multiple transactions. + +We can check the balance of the role: ``` basecli query account role:10CAFE4E