Skip to content
This repository has been archived by the owner on Aug 21, 2024. It is now read-only.

Commit

Permalink
Add auth sdk page (#108)
Browse files Browse the repository at this point in the history
* noop

* noop

* Update sdk and cli versions and output (#87)

* Update code samples in quickstart (#88)

* empty

* Update the tutorial for creating a project (#89)

* Update the tutorial for writing a contract (#90)

* Update the tutorial for testing (#91)

* Update the hello_world contract (#92)

* Small fix to hello contract

* Update the increment contract (#93)

* Small fix to increment example

* Update the custom_types contract (#94)

* Add auth example and update auth learn page (#95)

* Put auth example earlier in list of examples (#98)

(cherry picked from commit fc2fc75)

* Add events example (#100)

* Update the cross_contract contract (#99)

* Small tweak to contract call doc

* Fix to contract call code sample

* Fix to contract call code sample

* noop to try and make it deploy properly

* Reorder examples so that contract events appears higher in list

* Fix headings of cross contract example (#102)

* Add soroban-cli read example

* Tweak language about developer discord

* Some changes to the events example page (#101)

* Rename standard-contracts and update token-contract (#103)

* Rename Standard Contracts to Built-In Contracts

* Update built-in-contracts/token-contract and examples/authorization

* Fix title capitalization of built-in contracts page (#104)

* Add stub for token example (#105)

* Update authorization docs to line up with contract examples (#106)

* Small fixes for token contract doc

* Make authorization docs line up with the example

* Instruct users to checkout v0.0.4 tag for examples (#107)

* fix pages and sdk instructions

* Add auth sdk page

Co-authored-by: Tyler van der Hoeven <[email protected]>
Co-authored-by: Siddharth Suresh <[email protected]>
Co-authored-by: Jay Geng <[email protected]>
Co-authored-by: jonjove <[email protected]>
  • Loading branch information
5 people authored Sep 2, 2022
1 parent 799ae2d commit a23bf93
Show file tree
Hide file tree
Showing 22 changed files with 1,083 additions and 611 deletions.
40 changes: 40 additions & 0 deletions docs/SDKs/rust-auth.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
sidebar_position: 2
title: Soroban Rust Auth SDK
---

The `soroban-auth` Rust crate contains the Soroban Rust Auth SDK. It provides
utilities for verifying signatures on invocations of smart contracts. It is
intended for use alongside the [`soroban-sdk`].

[`soroban-sdk`]: rust

:::caution
The `soroban-auth` crate is in early development. Report issues
[here](https://github.com/stellar/rs-soroban-sdk/issues/new/choose).
:::

## SDK Documentation

Auth documentation is available at:
https://docs.rs/soroban-auth

## Subscribe to Releases

Subscribe to releases on the GitHub repository:
https://github.com/stellar/rs-soroban-sdk

## Add `soroban-auth` as a Dependency

Add the following sections to the `Cargo.toml` to import `soroban-auth`.

```toml
[features]
testutils = ["soroban-auth/testutils"]

[dependencies]
soroban-auth = "0.0.4"

[dev_dependencies]
soroban-auth = { version = "0.0.4", features = ["soroban-auth/testutils"] }
```
5 changes: 4 additions & 1 deletion docs/SDKs/rust.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,8 @@ Add the following sections to the `Cargo.toml` to import the `soroban-sdk`.
testutils = ["soroban-sdk/testutils"]

[dependencies]
soroban-sdk = "0.0.3"
soroban-sdk = "0.0.4"

[dev_dependencies]
soroban-sdk = { version = "0.0.4", features = ["soroban-sdk/testutils"] }
```
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"position": 3,
"label": "Standard Contracts",
"position": 5,
"label": "Built-in Contracts",
"link": {
"type": "generated-index"
}
Expand Down
172 changes: 172 additions & 0 deletions docs/built-in-contracts/token-contract.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
---
sidebar_position: 1
title: Token Contract
---

# Token Contract

The token contract is an implementation of [CAP-54 Smart Contract Standardized Asset].

[CAP-54 Smart Contract Standardized Asset]: https://stellar.org/protocol/cap-54

:::caution
The token contract is in early development, has not been audited, and is not
intended for use. Report issues
[here](https://github.com/stellar/soroban-token-contract/issues/new/choose).
:::

## Overview

Tokens are a vital part of blockchains, and contracts that implement token
functionality are inevitable on any smart contract platform. A built-in token
contract has a number of advantages over token contracts written by the
ecosystem. First, we can special case this contract and run it natively instead
of running in a WASM VM, reducing the cost of using the contract. Second, we
can use this built-in contract to allow "classic" Stellar assets to interoperate
with Soroban. The current iteration of the standard token contract doesn't
interoperate with "classic" Stellar assets, but this feature will be available
in the future. Note that this standard token contract does not prevent the
ecosystem from developing other token contracts if the standard is missing
functionality they require.

The standard token contract is similar to the widely used ERC-20 token standard,
which should make it easier for existing smart contract developers to get
started on Stellar.

## Token contract authorization semantics

See the [authorization example](../examples/authorization) for an overview of
authorization.

### Token operations

The token contract contains three kinds of operations

- getters, such as `balance`, which do not change the state of the contract
- unprivileged mutators, such as `approve` and `xfer`, which change the state of
the contract but do not require special privileges
- privileged mutators, such as `burn` and `set_admin`, which change the state of
the contract but require special privileges

Gettors require no authorization because they do not change the state of the
contract and all contract data is public. For example, `balance` simply returns
the balance of the specified identity without changing it.

Unprivileged mutators require authorization from some identity. The identity
which must provide authorization will vary depending on the unprivileged
mutator. For example, a "grantor" can use `approve` to allow a "spender" to spend
the grantor's money up to some limit. So for approve, the grantor must provide
authorization. Similarly, a "sender" can use `xfer` to send money to a
"recipient". So for `xfer`, the sender must provide authorization.

Priviliged mutators require authorization from a specific privileged identity,
known as the "administrator". For example, only the administrator can `mint` more
of the asset. Similarly, only the administrator can appoint a new administrator.

### Replay prevention

The token contract provides replay prevention by using a [nonce](https://en.wikipedia.org/wiki/Cryptographic_nonce).
The messages that are signed to provide authorization contain a nonce. The
contract also stores a nonce per identity. When checking signatures, the
contract loads the nonce for the relevant identity. When an operation succeeds,
the nonce stored in the contract is incremented. This makes it impossible to
reuse a signature.

The current nonce for an identity can be retrieved using the `nonce` contract
function.

### Example: Signing payloads

The [example](https://github.com/stellar/soroban-token-contract/blob/d24fbeaa3cad5406bee8b64e748a71fa38c7c2f3/src/testutils.rs#L48-L70)
from the test `Token` wrapper class demonstrate how you sign a payload for the
token contract.

```rust
pub fn approve(&self, from: &Keypair, spender: &Identifier, amount: &BigInt) {
let from_id = to_ed25519(&self.env, from);
let nonce = self.nonce(&from_id);

let msg = SignaturePayload::V0(SignaturePayloadV0 {
function: symbol!("approve"),
contract: self.contract_id.clone(),
network: self.env.ledger().network_passphrase(),
args: (from_id, &nonce, spender, amount).into_val(&self.env),
});

let auth = Signature::Ed25519(Ed25519Signature {
public_key: from.public.to_bytes().into_val(&self.env),
signature: from.sign(msg).unwrap().into_val(&self.env),
});
TokenClient::new(&self.env, &self.contract_id).approve(&auth, &nonce, &spender, &amount)
}
```

## Contract Interface

```rust
// Sets the administrator to "admin". Also sets some metadata
fn initialize(e: Env, admin: Identifier, decimal: u32, name: Bytes, symbol: Bytes);

// Admin interface -- these functions are privileged

// If "admin" is the administrator, burn "amount" from "from"
fn burn(e: Env, admin: Signature, nonce: BigInt, from: Identifier, amount: BigInt);

// If "admin" is the administrator, mint "amount" to "to"
fn mint(e: Env, admin: Signature, nonce: BigInt, to: Identifier, amount: BigInt);

// If "admin" is the administrator, set the administrator to "id"
fn set_admin(e: Env, admin: Signature, nonce: BigInt, new_admin: Identifier);

// If "admin" is the administrator, freeze "id"
fn freeze(e: Env, admin: Signature, nonce: BigInt, id: Identifier);

// If "admin" is the administrator, unfreeze "id"
fn unfreeze(e: Env, admin: Signature, nonce: BigInt, id: Identifier);

// Token Interface

// Get the allowance for "spender" to transfer from "from"
fn allowance(e: Env, from: Identifier, spender: Identifier) -> BigInt;

// Set the allowance to "amount" for "spender" to transfer from "from"
fn approve(e: Env, from: Signature, nonce: BigInt, spender: Identifier, amount: BigInt);

// Get the balance of "id"
fn balance(e: Env, id: Identifier) -> BigInt;

// Transfer "amount" from "from" to "to"
fn xfer(e: Env, from: Signature, nonce: BigInt, to: Identifier, amount: BigInt);

// Transfer "amount" from "from" to "to", consuming the allowance of "spender"
fn xfer_from(
e: Env,
spender: Signature,
nonce: BigInt,
from: Identifier,
to: Identifier,
amount: BigInt,
);

// Returns true if "id" is frozen
fn is_frozen(e: Env, id: Identifier) -> bool;

// Returns the current nonce for "id"
fn nonce(e: Env, id: Identifier) -> BigInt;

// Descriptive Interface

// Get the number of decimals used to represent amounts of this token
fn decimals(e: Env) -> u32;

// Get the name for this token
fn name(e: Env) -> Bytes;

// Get the symbol for this token
fn symbol(e: Env) -> Bytes;
```

## Interacting with the token contract in tests

See [interacting with contracts in tests](../learn/interacting-with-contracts#interacting-with-contracts-in-tests)
for more general information on this topic.
Loading

0 comments on commit a23bf93

Please sign in to comment.