From d2dcb9e249ca8710ab3839f5045fa528608e2764 Mon Sep 17 00:00:00 2001 From: radrow Date: Thu, 30 Apr 2020 00:02:26 +0200 Subject: [PATCH] Add AENS example, readd delegation signature chapter, fix links --- docs/sophia.md | 47 +++++++++++++++++++++++++++++++++++++++++++ docs/sophia_stdlib.md | 12 +++++------ 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/docs/sophia.md b/docs/sophia.md index a75062a..6478a1d 100644 --- a/docs/sophia.md +++ b/docs/sophia.md @@ -37,6 +37,7 @@ - [Example](#example) - [Sanity checks](#sanity-checks) - [AENS interface](#aens-interface) + - [Example](#example-1) - [Events](#events) - [Argument order](#argument-order) - [Compiler pragmas](#compiler-pragmas) @@ -55,6 +56,7 @@ - [Operators types](#operators-types) - [Operator precendences](#operator-precendences) - [Examples](#examples) + - [Delegation signature](#delegation-signature) ## The Sophia Language @@ -686,6 +688,43 @@ Contracts can interact with the [Aeternity Naming System](https://github.com/aeternity/protocol/blob/master/AENS.md). For this purpose the [AENS](sophia_stdlib.md#AENS) library was exposed. +#### Example + +In this example we assume that the name `name` already exists, and is owned by +an account with address `addr`. In order to allow a contract `ct` to handle +`name` the account holder needs to create a +[signature](#delegation-signature) `sig` of `addr | name.hash | ct.address`. + +Armed with this information we can for example write a function that extends +the name if it expires within 1000 blocks: +``` + stateful entrypoint extend_if_necessary(addr : address, name : string, sig : signature) = + switch(AENS.lookup(name)) + None => () + Some(AENS.Name(_, FixedTTL(expiry), _)) => + if(Chain.block_height + 1000 > expiry) + AENS.update(addr, name, Some(RelativeTTL(50000)), None, None, signature = sig) +``` + +And we can write functions that adds and removes keys from the pointers of the +name: +``` + stateful entrypoint add_key(addr : address, name : string, key : string, + pt : AENS.pointee, sig : signature) = + switch(AENS.lookup(name)) + None => () + Some(AENS.Name(_, _, ptrs)) => + AENS.update(addr, name, None, None, Some(ptrs{[key] = pt}), signature = sig) + + stateful entrypoint delete_key(addr : address, name : string, + key : string, sig : signature) = + switch(AENS.lookup(name)) + None => () + Some(AENS.Name(_, _, ptrs)) => + let ptrs = Map.delete(key, ptrs) + AENS.update(addr, name, None, None, Some(ptrs), signature = sig) +``` + ### Events @@ -1110,3 +1149,11 @@ contract FundMe = amount = state.contributions[to]}) put(state{ contributions @ c = Map.delete(to, c) }) ``` + +### Delegation signature + +Some chain operations (`Oracle.` and `AENS.`) have an +optional delegation signature. This is typically used when a user/accounts +would like to allow a contract to act on it's behalf. The exact data to be +signed varies for the different operations, but in all cases you should prepend +the signature data with the `network_id` (`ae_mainnet` for the Aeternity mainnet, etc.). diff --git a/docs/sophia_stdlib.md b/docs/sophia_stdlib.md index ece1f73..158b8df 100644 --- a/docs/sophia_stdlib.md +++ b/docs/sophia_stdlib.md @@ -348,7 +348,7 @@ Registers new oracle answering questions of type `'a` with answers of type `'b`. * The `acct` is the address of the oracle to register (can be the same as the contract). * `signature` is a signature proving that the contract is allowed to register the account - the account address + the contract address (concatenated as byte arrays) is - signed with the + [signed](./sophia.md#delegation-signature) with the private key of the account, proving you have the private key of the oracle to be. If the address is the same as the contract `sign` is ignored and can be left out entirely. * The `qfee` is the minimum query fee to be paid by a user when asking a question of the oracle. @@ -381,7 +381,7 @@ Responds to the question `q` on `o`. Unless the contract address is the same as the oracle address the `signature` (which is an optional, named argument) needs to be provided. Proving that we have the private key of the oracle by -signing the oracle query id + contract address +[signing](./sophia.md#delegation-signature) the oracle query id + contract address #### extend @@ -505,7 +505,7 @@ let Some(Name(owner, FixedTTL(expiry), ptrs)) = AENS.lookup("example.chain") AENS.preclaim(owner : address, commitment_hash : hash, ) : unit ``` -The signature should be over `owner address` + `Contract.address` +The [signature](./sophia.md#delegation-signature) should be over `owner address` + `Contract.address` (concatenated as byte arrays). @@ -514,7 +514,7 @@ The signature should be over `owner address` + `Contract.address` AENS.claim(owner : address, name : string, salt : int, name_fee : int, ) : unit ``` -The signature should be over `owner address` + `name_hash` + `Contract.address` +The [signature](./sophia.md#delegation-signature) should be over `owner address` + `name_hash` + `Contract.address` using the private key of the `owner` account for signing. @@ -525,7 +525,7 @@ AENS.transfer(owner : address, new_owner : address, name_hash : hash, ) : unit Revokes the name to extend the ownership time. -The signature should be over `owner address` + `name_hash` + `Contract.address` +The [signature](./sophia.md#delegation-signature) should be over `owner address` + `name_hash` + `Contract.address` using the private key of the `owner` account for signing.