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

Commit 98ffc86

Browse files
authoredSep 2, 2022
Merge pull request #85 from stellar/dev
2 parents 4238d07 + c1a57c5 commit 98ffc86

22 files changed

+1083
-611
lines changed
 

‎docs/SDKs/rust-auth.mdx

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
---
2+
sidebar_position: 2
3+
title: Soroban Rust Auth SDK
4+
---
5+
6+
The `soroban-auth` Rust crate contains the Soroban Rust Auth SDK. It provides
7+
utilities for verifying signatures on invocations of smart contracts. It is
8+
intended for use alongside the [`soroban-sdk`].
9+
10+
[`soroban-sdk`]: rust
11+
12+
:::caution
13+
The `soroban-auth` crate is in early development. Report issues
14+
[here](https://github.com/stellar/rs-soroban-sdk/issues/new/choose).
15+
:::
16+
17+
## SDK Documentation
18+
19+
Auth documentation is available at:
20+
https://docs.rs/soroban-auth
21+
22+
## Subscribe to Releases
23+
24+
Subscribe to releases on the GitHub repository:
25+
https://github.com/stellar/rs-soroban-sdk
26+
27+
## Add `soroban-auth` as a Dependency
28+
29+
Add the following sections to the `Cargo.toml` to import `soroban-auth`.
30+
31+
```toml
32+
[features]
33+
testutils = ["soroban-auth/testutils"]
34+
35+
[dependencies]
36+
soroban-auth = "0.0.4"
37+
38+
[dev_dependencies]
39+
soroban-auth = { version = "0.0.4", features = ["soroban-auth/testutils"] }
40+
```

‎docs/SDKs/rust.mdx

+4-1
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,8 @@ Add the following sections to the `Cargo.toml` to import the `soroban-sdk`.
2929
testutils = ["soroban-sdk/testutils"]
3030

3131
[dependencies]
32-
soroban-sdk = "0.0.3"
32+
soroban-sdk = "0.0.4"
33+
34+
[dev_dependencies]
35+
soroban-sdk = { version = "0.0.4", features = ["soroban-sdk/testutils"] }
3336
```

‎docs/standard-contracts/_category_.json ‎docs/built-in-contracts/_category_.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
2-
"position": 3,
3-
"label": "Standard Contracts",
2+
"position": 5,
3+
"label": "Built-in Contracts",
44
"link": {
55
"type": "generated-index"
66
}
+172
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
---
2+
sidebar_position: 1
3+
title: Token Contract
4+
---
5+
6+
# Token Contract
7+
8+
The token contract is an implementation of [CAP-54 Smart Contract Standardized Asset].
9+
10+
[CAP-54 Smart Contract Standardized Asset]: https://stellar.org/protocol/cap-54
11+
12+
:::caution
13+
The token contract is in early development, has not been audited, and is not
14+
intended for use. Report issues
15+
[here](https://github.com/stellar/soroban-token-contract/issues/new/choose).
16+
:::
17+
18+
## Overview
19+
20+
Tokens are a vital part of blockchains, and contracts that implement token
21+
functionality are inevitable on any smart contract platform. A built-in token
22+
contract has a number of advantages over token contracts written by the
23+
ecosystem. First, we can special case this contract and run it natively instead
24+
of running in a WASM VM, reducing the cost of using the contract. Second, we
25+
can use this built-in contract to allow "classic" Stellar assets to interoperate
26+
with Soroban. The current iteration of the standard token contract doesn't
27+
interoperate with "classic" Stellar assets, but this feature will be available
28+
in the future. Note that this standard token contract does not prevent the
29+
ecosystem from developing other token contracts if the standard is missing
30+
functionality they require.
31+
32+
The standard token contract is similar to the widely used ERC-20 token standard,
33+
which should make it easier for existing smart contract developers to get
34+
started on Stellar.
35+
36+
## Token contract authorization semantics
37+
38+
See the [authorization example](../examples/authorization) for an overview of
39+
authorization.
40+
41+
### Token operations
42+
43+
The token contract contains three kinds of operations
44+
45+
- getters, such as `balance`, which do not change the state of the contract
46+
- unprivileged mutators, such as `approve` and `xfer`, which change the state of
47+
the contract but do not require special privileges
48+
- privileged mutators, such as `burn` and `set_admin`, which change the state of
49+
the contract but require special privileges
50+
51+
Gettors require no authorization because they do not change the state of the
52+
contract and all contract data is public. For example, `balance` simply returns
53+
the balance of the specified identity without changing it.
54+
55+
Unprivileged mutators require authorization from some identity. The identity
56+
which must provide authorization will vary depending on the unprivileged
57+
mutator. For example, a "grantor" can use `approve` to allow a "spender" to spend
58+
the grantor's money up to some limit. So for approve, the grantor must provide
59+
authorization. Similarly, a "sender" can use `xfer` to send money to a
60+
"recipient". So for `xfer`, the sender must provide authorization.
61+
62+
Priviliged mutators require authorization from a specific privileged identity,
63+
known as the "administrator". For example, only the administrator can `mint` more
64+
of the asset. Similarly, only the administrator can appoint a new administrator.
65+
66+
### Replay prevention
67+
68+
The token contract provides replay prevention by using a [nonce](https://en.wikipedia.org/wiki/Cryptographic_nonce).
69+
The messages that are signed to provide authorization contain a nonce. The
70+
contract also stores a nonce per identity. When checking signatures, the
71+
contract loads the nonce for the relevant identity. When an operation succeeds,
72+
the nonce stored in the contract is incremented. This makes it impossible to
73+
reuse a signature.
74+
75+
The current nonce for an identity can be retrieved using the `nonce` contract
76+
function.
77+
78+
### Example: Signing payloads
79+
80+
The [example](https://github.com/stellar/soroban-token-contract/blob/d24fbeaa3cad5406bee8b64e748a71fa38c7c2f3/src/testutils.rs#L48-L70)
81+
from the test `Token` wrapper class demonstrate how you sign a payload for the
82+
token contract.
83+
84+
```rust
85+
pub fn approve(&self, from: &Keypair, spender: &Identifier, amount: &BigInt) {
86+
let from_id = to_ed25519(&self.env, from);
87+
let nonce = self.nonce(&from_id);
88+
89+
let msg = SignaturePayload::V0(SignaturePayloadV0 {
90+
function: symbol!("approve"),
91+
contract: self.contract_id.clone(),
92+
network: self.env.ledger().network_passphrase(),
93+
args: (from_id, &nonce, spender, amount).into_val(&self.env),
94+
});
95+
96+
let auth = Signature::Ed25519(Ed25519Signature {
97+
public_key: from.public.to_bytes().into_val(&self.env),
98+
signature: from.sign(msg).unwrap().into_val(&self.env),
99+
});
100+
TokenClient::new(&self.env, &self.contract_id).approve(&auth, &nonce, &spender, &amount)
101+
}
102+
```
103+
104+
## Contract Interface
105+
106+
```rust
107+
// Sets the administrator to "admin". Also sets some metadata
108+
fn initialize(e: Env, admin: Identifier, decimal: u32, name: Bytes, symbol: Bytes);
109+
110+
// Admin interface -- these functions are privileged
111+
112+
// If "admin" is the administrator, burn "amount" from "from"
113+
fn burn(e: Env, admin: Signature, nonce: BigInt, from: Identifier, amount: BigInt);
114+
115+
// If "admin" is the administrator, mint "amount" to "to"
116+
fn mint(e: Env, admin: Signature, nonce: BigInt, to: Identifier, amount: BigInt);
117+
118+
// If "admin" is the administrator, set the administrator to "id"
119+
fn set_admin(e: Env, admin: Signature, nonce: BigInt, new_admin: Identifier);
120+
121+
// If "admin" is the administrator, freeze "id"
122+
fn freeze(e: Env, admin: Signature, nonce: BigInt, id: Identifier);
123+
124+
// If "admin" is the administrator, unfreeze "id"
125+
fn unfreeze(e: Env, admin: Signature, nonce: BigInt, id: Identifier);
126+
127+
// Token Interface
128+
129+
// Get the allowance for "spender" to transfer from "from"
130+
fn allowance(e: Env, from: Identifier, spender: Identifier) -> BigInt;
131+
132+
// Set the allowance to "amount" for "spender" to transfer from "from"
133+
fn approve(e: Env, from: Signature, nonce: BigInt, spender: Identifier, amount: BigInt);
134+
135+
// Get the balance of "id"
136+
fn balance(e: Env, id: Identifier) -> BigInt;
137+
138+
// Transfer "amount" from "from" to "to"
139+
fn xfer(e: Env, from: Signature, nonce: BigInt, to: Identifier, amount: BigInt);
140+
141+
// Transfer "amount" from "from" to "to", consuming the allowance of "spender"
142+
fn xfer_from(
143+
e: Env,
144+
spender: Signature,
145+
nonce: BigInt,
146+
from: Identifier,
147+
to: Identifier,
148+
amount: BigInt,
149+
);
150+
151+
// Returns true if "id" is frozen
152+
fn is_frozen(e: Env, id: Identifier) -> bool;
153+
154+
// Returns the current nonce for "id"
155+
fn nonce(e: Env, id: Identifier) -> BigInt;
156+
157+
// Descriptive Interface
158+
159+
// Get the number of decimals used to represent amounts of this token
160+
fn decimals(e: Env) -> u32;
161+
162+
// Get the name for this token
163+
fn name(e: Env) -> Bytes;
164+
165+
// Get the symbol for this token
166+
fn symbol(e: Env) -> Bytes;
167+
```
168+
169+
## Interacting with the token contract in tests
170+
171+
See [interacting with contracts in tests](../learn/interacting-with-contracts#interacting-with-contracts-in-tests)
172+
for more general information on this topic.

0 commit comments

Comments
 (0)
This repository has been archived.