Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 20 additions & 20 deletions docs/build/smart-contracts/example-contracts/tokens.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ This example shows how to build a token from scratch using only the `soroban-sdk

[open-in-github-codespaces]: https://github.com/codespaces/new?repo=stellar/soroban-examples&editor=web
[open-in-code-anywhere]: https://app.codeanywhere.com/#https://github.com/stellar/soroban-examples
[token example]: https://github.com/stellar/soroban-examples/tree/v23.0.0/token
[token example]: https://github.com/stellar/soroban-examples/tree/main/token
Comment thread
Copilot marked this conversation as resolved.
[token interface]: ../../../tokens/token-interface.mdx

:::info[Whisk Changes]
Expand All @@ -46,10 +46,10 @@ With the release of Whisk, Protocol 23, the [token interface] has seen some chan

## Run the Example

First go through the [Setup] process to get your development environment configured, then clone the `v23.0.0` tag of `soroban-examples` repository:
First go through the [Setup] process to get your development environment configured, then clone the `soroban-examples` repository:

```sh
git clone -b v23.0.0 https://github.com/stellar/soroban-examples
git clone https://github.com/stellar/soroban-examples
```

Or, skip the development environment setup and open this example in [GitHub Codespaces][open-in-github-codespaces] or [Code Anywhere][open-in-code-anywhere].
Expand Down Expand Up @@ -129,18 +129,18 @@ use soroban_sdk::{Address, Env};
pub fn read_allowance(e: &Env, from: Address, spender: Address) -> AllowanceValue {
let key = DataKey::Allowance(AllowanceDataKey { from, spender });
if let Some(allowance) = e.storage().temporary().get::<_, AllowanceValue>(&key) {
if allowance.expiration_ledger < e.ledger().sequence() {
if allowance.live_until_ledger < e.ledger().sequence() {
AllowanceValue {
amount: 0,
expiration_ledger: allowance.expiration_ledger,
live_until_ledger: allowance.live_until_ledger,
}
} else {
allowance
}
} else {
AllowanceValue {
amount: 0,
expiration_ledger: 0,
live_until_ledger: 0,
}
}
}
Expand All @@ -150,22 +150,22 @@ pub fn write_allowance(
from: Address,
spender: Address,
amount: i128,
expiration_ledger: u32,
live_until_ledger: u32,
) {
let allowance = AllowanceValue {
amount,
expiration_ledger,
live_until_ledger,
};

if amount > 0 && expiration_ledger < e.ledger().sequence() {
panic!("expiration_ledger is less than ledger seq when amount > 0")
if amount > 0 && live_until_ledger < e.ledger().sequence() {
panic!("live_until_ledger is less than ledger seq when amount > 0")
}

let key = DataKey::Allowance(AllowanceDataKey { from, spender });
e.storage().temporary().set(&key.clone(), &allowance);

if amount > 0 {
let live_for = expiration_ledger
let live_for = live_until_ledger
.checked_sub(e.ledger().sequence())
.unwrap();

Expand All @@ -184,7 +184,7 @@ pub fn spend_allowance(e: &Env, from: Address, spender: Address, amount: i128) {
from,
spender,
allowance.amount - amount,
allowance.expiration_ledger,
allowance.live_until_ledger,
);
}
}
Expand Down Expand Up @@ -319,7 +319,7 @@ impl Token {
}
}

#[contractimpl]
#[contractimpl(contracttrait)]
impl TokenInterface for Token {
fn allowance(e: Env, from: Address, spender: Address) -> i128 {
e.storage()
Expand All @@ -328,7 +328,7 @@ impl TokenInterface for Token {
read_allowance(&e, from, spender).amount
}

fn approve(e: Env, from: Address, spender: Address, amount: i128, expiration_ledger: u32) {
fn approve(e: Env, from: Address, spender: Address, amount: i128, live_until_ledger: u32) {
Comment thread
leighmcculloch marked this conversation as resolved.
from.require_auth();

check_nonnegative_amount(amount);
Expand All @@ -337,12 +337,12 @@ impl TokenInterface for Token {
.instance()
.extend_ttl(INSTANCE_LIFETIME_THRESHOLD, INSTANCE_BUMP_AMOUNT);

write_allowance(&e, from.clone(), spender.clone(), amount, expiration_ledger);
write_allowance(&e, from.clone(), spender.clone(), amount, live_until_ledger);
events::Approve {
from,
spender,
amount,
expiration_ledger,
expiration_ledger: live_until_ledger,
}
.publish(&e);
}
Expand Down Expand Up @@ -489,7 +489,7 @@ pub struct AllowanceDataKey {
#[contracttype]
pub struct AllowanceValue {
pub amount: i128,
pub expiration_ledger: u32,
pub live_until_ledger: u32,
}

#[derive(Clone)]
Expand All @@ -505,7 +505,7 @@ pub enum DataKey {
</TabItem>
</Tabs>

Ref: https://github.com/stellar/soroban-examples/tree/v23.0.0/token
Ref: https://github.com/stellar/soroban-examples/tree/main/token

## How it Works

Expand Down Expand Up @@ -599,7 +599,7 @@ Of course, you will want your token to behave in an _intuitive_ and _transparent

## Tests

Open the [`token/src/test.rs`](https://github.com/stellar/soroban-examples/tree/v23.0.0/token/src/test.rs) file to follow along.
Open the [`token/src/test.rs`](https://github.com/stellar/soroban-examples/tree/main/token/src/test.rs) file to follow along.

```rust title="token/src/test.rs"
#![cfg(test)]
Expand Down Expand Up @@ -877,7 +877,7 @@ fn test_zero_allowance() {
}
```

The token example implements eight different tests to cover a wide array of potential behaviors and problems. However, all of the tests start with a few common pieces. In any test, the first thing that is always required is an `Env`, which is the Soroban environment that the contract will run in.
The token example implements six different tests to cover a wide array of potential behaviors and problems. However, all of the tests start with a few common pieces. In any test, the first thing that is always required is an `Env`, which is the Soroban environment that the contract will run in.

```rust
let e = Env::default();
Expand Down
Loading