In this lesson, we go over how to secure coins using signatures.
- Signing and Signatures: Understand the uses and benefits of signatures.
- Chialisp Library files: Learn about helpful Chialisp libraries to simplify development.
Expand for the full script
We created our first smart coin and secured it so that only someone with the correct password could spend it. In this video, we'll use a signature to secure our coin so that only the person with the correct signature will be able to spend the coin.
So what is a signature? A digital signature allows you to sign a message with a private key. This message can then be verified by a recipient using your public key. Let's start with an example of signing a message and then verifying it.
chia keys sign --message with the message
"hello" --hdpath m then choose your wallet ID. This process will sign the message 'hello' with your private key. To verify this message we'll run
chia keys verify enter the message, then the signature and the sender's public key. (
chia keys verify --message hello --signature [SIG] --public_key [PUB_KEY])
So now that we know how signing works, let's create a coin that can be spent when given the correct signature. So in our chialisp file, let's define a module that takes two parameters. The first will be a public key that we'll curry in later. This will determine who is able to spend the coin.
The second parameter will be the conditions that determine how the coin will be spent. Next, we'll include some libraries to make our code a bit easier to write. The first lets us use written condition codes rather than number codes, and the second is a library for tree hashing.
To install these libraries, run this command in the terminal.
cdv clsp retrieve sha256tree condition-codes. Back to our chialisp file, we'll define a combine statement with
c and for the first parameter, create a list composed of the
AGG_SIG_ME condition, our public key parameter and the conditions parameter run through the tree hashing library. (
(c (list AGG_SIG_ME PUBLIC_KEY (sha256tree conditions)) conditions))
The second parameter in the combine statement will be the conditions that are passed into the program. So what does this do? Well the
AGG_SIG_ME condition is a standard condition that signs a message with a public key. In this case we are currying in the key and the message is the tree hash of the conditions parameter.
We do this so that the conditions cannot be modified by the farmer. So in order to spend the coin, the user must provide a solution that contains a list of conditions; or how they'd like to spend the coin; as well as a signature to show that they are the ones authorized to do so.
For this example, we're going to create a solution that uses the
CREATE_COIN condition to essentially unlock the value of the coin and send it back to our wallet. First, let's finish creating this coin. We'll get our master public key with
chia keys show and curry that into our program. It's important to prefix the key with
0x to show that it is a value.
Now we'll get the puzzle reveal with
opc and enter in the compiled code. Make sure to save this for later. And for the puzzle hash we'll run
opc -h and enter the compiled code. We'll save this for later as well. We'll need to take the puzzle hash and encode it into an address. Run
cdv encode --prefix txch and enter the puzzle hash.
That gives us the puzzle address. Now we'll send an amount of chia to this address to lock it. And we'll check the status. Once confirmed, we'll be ready to spend it.
To spend the coin, we'll need to create a spend bundle. Take a look at this outline. this should look familiar to the spend bundle we created in the previous video. We'll need four things, the coin record, the puzzle reveal which we already calculated, the solution we want to provide, and an aggregated signature to authorize our spend.
To get the coin record, run
cdv rpc coinrecords --by puzzlehash and enter the puzzle hash from earlier. Copy the coin object and paste it into the spend bundle template. Next we can enter the puzzle reveal we calculated earlier. For the solution, we're going to have to so some work.
We'll use the standard condition
CREATE_COIN to unlock the value of the coin and send it back to our wallet. To do that, we'll need our address which we can get with
chia wallet get address and decode it to get the wallet address puzzle hash with
cdv decode and our address.
To craft the solution, we'll run this command where
51 is the
CREATE_COIN condition code, our wallet address puzzle hash, and an amount in mojo. We can enter this response into the solution of our spend bundle.
Finally, the aggregated signature. Remember that the message we are signing is the tree hash of our conditions; or our solution. So first, let's generate that hash. Next we'll also need the coin ID and the genesis challenge. The genesis challenge is a standard value for each network.
You can find the appropriate challenge by entering
chia show -s and searching for 'genesis challenge'. For the coin ID, we actually need the parent ID, the puzzle hash, and the amount which can all be found in the coin record we copied earlier.
To get the coin ID, we'll run
cdv inspect -id coins enter the parent ID, the puzzle hash, and the amount. (
cdv inspect -id coins --parent-id [PARENT_ID] --puzzle-hash [PUZZLE_HASH] --amount [AMOUNT]) The
AGG_SIG_ME condition expects the concatenation of the conditions treehash, coin ID, and genesis challenge, so run
concat the conditions treehash, coin ID, and genesis challenge. Make sure to use the prefix
0x to signify that these are values. Now let's sign this message and since we're NOT using it as a value, remember to remove the
0x prefix this time.
Now we can enter this signature into our spend bundle and push it. Run
cdv rpc pushtx spendbundle.json. If your signature is incorrect, you'll get a failure message. Otherwise, congratulations! You've created a smart coin secured with a signature and spent it.
So we've talked in this video about how signatures work, their importance, and how to implement them into a smart coin. Thanks so much for watching, I'll see you next time.
- 0x Prefixes: It's important to keep track of how we are using different values and understand how Chialisp is going to handle them. A common gotcha is forgetting to append
0xto a value, or in some cases removing it to tell the puzzle how to properly handle the parameter.
- "Saving for Later": At several points in this lesson, we generate results that we'll need to use elsewhere, sometimes many times. These results also do not have obivious indicators as to what they are. It's helpful to have a document to temporarily store these results for later use.
True or False. You need to use someone's private key to lock up a coin for them to spend.
Answer (expand when ready to see the answer)
False. You would use their public key. Private keys are to be kept secret and never revealed to anyone.
An Aggregated Signature is comprised of which three components?
Answer (expand when ready to see the answer)
AGG_SIG_ME condition expects a concatenated value of the following:
- The conditions treehash.
- The coin ID.
- The genesis challenge.
Runnable Chialisp and clvm plugins
For information on using these plugins please refer to the academy overview
- General chialisp concepts: overviews of currying, inner puzzles, and morphing conditions.
- Guided chialisp walkthroughs: guides for installation, creating smart coins, and working with BLS signatures.
- Chialisp detailed documentation: detailed information on all aspects of chialisp.
- Support in discord: for further support join our discord server and ask in the #chialisp or #support channels.