doc/testnet: smart contracts deployment documentation added

This commit is contained in:
skoupidi
2025-10-28 21:04:12 +02:00
parent fe6efa2eaa
commit afdf2d6440
4 changed files with 271 additions and 1 deletions

View File

@@ -16,6 +16,7 @@
- [Payments](testnet/payment.md)
- [Atomic Swap](testnet/atomic-swap.md)
- [DAO](testnet/dao.md)
- [Contracts](testnet/contract.md)
- [DarkIRC](misc/darkirc/darkirc.md)
- [Private Message](misc/darkirc/private_message.md)
- [Node Configurations](misc/nodes/node-configurations.md)

267
doc/src/testnet/contract.md Normal file
View File

@@ -0,0 +1,267 @@
# Custom Smart Contracts
Users can deploy their own zero-knowledge contracts, written for the
DarkFi [zkVM](../zkas/index.md), becoming anonymous engineers
themselves!
More information about the smart contracts architecture can be found
[here](../arch/sc/sc.md).
## Hello World
For the porpuses of this guide, an example smart contract is provided,
which users can deploy to the testnet and interact with. This is a very
simple smart contract simulating a registration ledger, where users can
register or remove themselves from it, and each user is represented as
the [poseidon hash](../spec/crypto-schemes.md#poseidonhash-function) of their
public key.
First, open another terminal and navigate (from repo root) to the
example:
```shell
$ cd example/wasm-hello-world
```
Here, generate the contract `WASM` bincode by executing:
```shell
$ make
"../../zkas" proof/secret_commitment.zk -o proof/secret_commitment.zk.bin
Wrote output to proof/secret_commitment.zk.bin
RUSTFLAGS="" cargo build --target=wasm32-unknown-unknown \
--release --package wasm_hello_world
...
Compiling wasm_hello_world v0.0.1 (/home/anon/darkfi/example/wasm-hello-world)
Finished `release` profile [optimized] target(s) in 15.90s
cp -f target/wasm32-unknown-unknown/release/wasm_hello_world.wasm wasm_hello_world.wasm
wasm-strip wasm_hello_world.wasm
```
Apart from the contract, an example client to interact with it is
provided, which we also need to compile:
```shell
$ cd client
$ make
RUSTFLAGS="" cargo build --target=x86_64-unknown-linux-gnu --release --package client
...
Compiling client v0.0.1 (/home/anon/darkfi/example/wasm-hello-world/client)
Finished `release` profile [optimized] target(s) in 2m 29s
cp -f target/x86_64-unknown-linux-gnu/release/client client
```
Now both the contract and its client are ready to use. Leave this
terminal open, as we will come back to it later in the guide, and
return back to your `drk` interactive shell.
## Creating contracts
Each contract is controlled by a secret key, from which its Contract ID
derives. To deploy a smart contract, we need to generate an authority
keypair first. The Contract ID shown in the outputs is a placeholder
for the one that will be generated from you. In rest of the guide, use
the one you generated by replacing the corresponding placeholder. We
can create our own contract authority by executing the following
command:
```shell
drk> contract generate-deploy
Generating a new keypair
Created new contract deploy authority
Contract ID: {CONTRACT_ID}
```
You can list your mint authorities with:
```shell
drk> contract list
Index | Contract ID | Locked | Lock Height
-------+---------------+--------+-------------
1 | {CONTRACT_ID} | false | -
```
## Deploy transaction
Now that we have a contract authority, we can deploy the example
contract we compiled earlier using it:
```shell
drk> contract deploy {CONTRACT_ID} example/wasm-hello-world/wasm_hello_world.wasm | broadcast
[mark_tx_spend] Processing transaction: d0824bb0ecb9b12af69579c01c570c0275e399b80ef10f0a9c645af65bdd0415
[mark_tx_spend] Found Money contract in call 1
Broadcasting transaction...
Transaction ID: d0824bb0ecb9b12af69579c01c570c0275e399b80ef10f0a9c645af65bdd0415
```
Now the transaction should be published to the network. When the
transaction is confirmed, the contract history will show its record:
```shell
drk> contract list {CONTRACT_ID}
Transaction Hash | Type | Block Height
------------------+------------+--------------
{TX_HASH} | DEPLOYMENT | 34
```
We can redeploy the contract as many times as we want, as long as it's
not locked. Each redeployment will show a new record in the contract
history. We can also export the deployed data by executing:
```shell
drk> contract export-data {TX_HASH} > wasm_hello_world.dat
```
The exported files contains the `WASM` bincode and instruction data
deployed by that transaction, encoded in `base64` as a tuple.
## Lock transaction
After we finished deploying our contract and don't require further code
changes, we can lock it. This will not allow further deployment
transactions, effectively locking the smart contract on-chain code. To
lock down the contract, execute:
```shell
drk> contract lock {CONTRACT_ID} | broadcast
[mark_tx_spend] Processing transaction: 9eee9799d77d0ef1dd115738982296c9c481b4412c75a0a0955fd67d87bfe6a0
[mark_tx_spend] Found Money contract in call 1
Broadcasting transaction...
Transaction ID: 9eee9799d77d0ef1dd115738982296c9c481b4412c75a0a0955fd67d87bfe6a0
```
After the transaction has been confirmed, we will see our contract
`Locked` status set to `true`, along with the block height it was
locked on:
```shell
drk> contract list
Index | Contract ID | Locked | Lock Height
-------+---------------+--------+-------------
1 | {CONTRACT_ID} | true | 36
```
We will also see the lock transaction in its history:
```shell
drk> contract list {CONTRACT_ID}
Transaction Hash | Type | Block Height
------------------+------------+--------------
{TX_HASH} | DEPLOYMENT | 34
{LOCK_TX_HASH} | LOCK | 36
```
## Interacting with the smart contract
Now that the contract code is set on-chain and cannot be modified
further, let's interact with it using its client!
> NOTE: This is a very basic example client so secrets keys are used
> as plainext for simplicity. Do not run this in a machine with
> commands history or in a hostile environment where your secret key
> can be exposed.
First lets generate a new throwaway address to register:
```shell
drk> wallet keygen
Generating a new keypair
New address:
{DUMMY_ADDRESS}
```
Set it as the default one in the wallet and grab its secret key:
```shell
drk> wallet addresses
Key ID | Public Key | Secret Key | Is Default
-----------------------+------------------+-----------------------------+------------
1 | {NORMAL_ADDRESS} | {NORMAL_ADDRESS_SECRET_KEY} | *
...
{DUMMY_ADDRESS_INDEX} | {DUMMY_ADDRESS} | {DUMMY_ADDRESS_SECRET_KEY} |
drk> wallet default-address {DUMMY_ADDRESS_INDEX}
```
### List members
Let's go to the contract client terminal, and check current members:
```shell
$ ./client -c {CONTRACT_ID} list
{CONTRACT_ID} members:
No members found
```
No one has registered yet, so let's change that!
### Registration
Let's go to the contract client terminal, and register ourselves:
```shell
$ ./client -c {CONTRACT_ID} register {DUMMY_ADDRESS_SECRET_KEY} > register.tx
```
The produced transaction doesn't contain a fee, so we need to attach it
in our `drk` interactive shell:
```shell
drk> attach-fee < example/wasm-hello-world/client/register.tx | broadcast
[mark_tx_spend] Processing transaction: 23ea7d01ae16389e71d73fa27748ce1633d39c6b55a4aa31d8f5ba1017a4f840
[mark_tx_spend] Found Money contract in call 1
Broadcasting transaction...
Transaction ID: 23ea7d01ae16389e71d73fa27748ce1633d39c6b55a4aa31d8f5ba1017a4f840
```
After a while, we will see a new member in our contract registry:
```shell
$ ./client -c {CONTRACT_ID} list
{CONTRACT_ID} members:
1. 0x242d4a0dc358e0b61053c28352f666bace79889559b65e91efd1c83c7c817fdd
```
### Deregistration
To remove ourselves from the registry, we create a deregister
transaction with the contract client:
```shell
$ ./client -c {CONTRACT_ID} deregister {DUMMY_ADDRESS_SECRET_KEY} > deregister.tx
```
Then, we attach the fee again and broadcast it to the network:
```shell
drk> attach-fee < example/wasm-hello-world/client/deregister.tx | broadcast
[mark_tx_spend] Processing transaction: f3304e6f5673d9ece211af6dd85c70ec8c8e85e91439b8cffbcf5387b11de1d0
[mark_tx_spend] Found Money contract in call 1
Broadcasting transaction...
Transaction ID: f3304e6f5673d9ece211af6dd85c70ec8c8e85e91439b8cffbcf5387b11de1d0
```
When the transaction gets confirmed, our registry will not have members
again:
```shell
$ ./client -c {CONTRACT_ID} list
{CONTRACT_ID} members:
No members found
```

View File

@@ -449,7 +449,8 @@ $ ./wallet-balance.sh
Don't forget that when using this local node, all operations
should be executed inside the `contrib/localnet/darkfid-single-node`
folder, and `./drk` command to be replaced by `../../../drk -c drk.toml`
folder, and `./drk` command to be replaced by
`../../../drk -c drk.toml`. All paths should be relative to this one.
## Advanced Usage

View File

@@ -21,6 +21,7 @@ You can check your wallet balance using `drk`:
```shell
drk> wallet balance
Token ID | Aliases | Balance
----------------------------------------------+---------+---------
241vANigf1Cy3ytjM1KHXiVECxgxdK4yApddL8KcLssb | DRK | 20