Skip to content

Commit b726d6c

Browse files
authored
feat: Add NFT contract (#82)
* Add nft example contract * Fixup references for deployed contracts to use {} * Update hello world to use Stellar vs Soroban, add constructor for NFT * Update all OZ references * Update fungible token example * Update package-lock
1 parent 3a3f587 commit b726d6c

20 files changed

+2203
-148
lines changed

Cargo.lock

Lines changed: 54 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
[workspace]
2+
members = ["contracts/*"]
23
resolver = "2"
3-
members = [
4-
"contracts/*",
5-
]
64

75
[workspace.package]
86
authors = ["AhaLabs"]
@@ -11,24 +9,42 @@ license = "Apache-2.0"
119
repository = "https://github.com/AhaLabs/scaffold-stellar"
1210
version = "0.0.1"
1311

14-
[workspace.dependencies]
15-
soroban-sdk = { version = "22.0.7" }
16-
soroban-token-sdk = { version = "22.0.1" }
17-
stellar-pausable = { git = "https://github.com/OpenZeppelin/stellar-contracts", tag = "v0.2.0" }
18-
stellar-pausable-macros = { git = "https://github.com/OpenZeppelin/stellar-contracts", tag = "v0.2.0" }
19-
stellar-fungible = { git = "https://github.com/OpenZeppelin/stellar-contracts", tag = "v0.2.0" }
12+
[workspace.dependencies.soroban-sdk]
13+
version = "22.0.7"
14+
15+
[workspace.dependencies.soroban-token-sdk]
16+
version = "22.0.1"
17+
18+
[workspace.dependencies.stellar-default-impl-macro]
19+
git = "https://github.com/OpenZeppelin/stellar-contracts"
20+
tag = "v0.3.0"
21+
22+
[workspace.dependencies.stellar-fungible]
23+
git = "https://github.com/OpenZeppelin/stellar-contracts"
24+
tag = "v0.3.0"
25+
26+
[workspace.dependencies.stellar-non-fungible]
27+
git = "https://github.com/OpenZeppelin/stellar-contracts"
28+
tag = "v0.3.0"
29+
30+
[workspace.dependencies.stellar-pausable]
31+
git = "https://github.com/OpenZeppelin/stellar-contracts"
32+
tag = "v0.3.0"
33+
34+
[workspace.dependencies.stellar-pausable-macros]
35+
git = "https://github.com/OpenZeppelin/stellar-contracts"
36+
tag = "v0.3.0"
2037

2138
[profile.release]
2239
opt-level = "z"
23-
overflow-checks = true
24-
debug = 0
25-
strip = "symbols"
40+
debug = false
41+
lto = true
2642
debug-assertions = false
27-
panic = "abort"
2843
codegen-units = 1
29-
lto = true
44+
panic = "abort"
45+
overflow-checks = true
46+
strip = true
3047

31-
# For more information about this profile see https://soroban.stellar.org/docs/basic-tutorials/logging#cargotoml-profile
3248
[profile.release-with-logs]
33-
inherits = "release"
3449
debug-assertions = true
50+
inherits = "release"

contracts/fungible-token-interface/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
name = "fungible-token-interface-example"
33
edition.workspace = true
44
license.workspace = true
5-
repository = "https://github.com/OpenZeppelin/stellar-contracts"
5+
repository.workspace = true
66
publish = false
77
version.workspace = true
88

contracts/fungible-token-interface/src/contract.rs

Lines changed: 29 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use soroban_sdk::{
1717
contract, contracterror, contractimpl, panic_with_error, symbol_short, token::TokenInterface,
1818
Address, Env, String, Symbol,
1919
};
20-
use stellar_fungible::{self as fungible, mintable::FungibleMintable};
20+
use stellar_fungible::Base;
2121
use stellar_pausable::{self as pausable, Pausable};
2222
use stellar_pausable_macros::when_not_paused;
2323

@@ -36,20 +36,26 @@ pub enum ExampleContractError {
3636
#[contractimpl]
3737
impl ExampleContract {
3838
pub fn __constructor(e: &Env, owner: Address, initial_supply: i128) {
39-
fungible::metadata::set_metadata(
40-
e,
41-
18,
42-
String::from_str(e, "My Token"),
43-
String::from_str(e, "TKN"),
44-
);
45-
fungible::mintable::mint(e, &owner, initial_supply);
39+
Base::set_metadata(e, 18, String::from_str(e, "My Token"), String::from_str(e, "TKN"));
40+
Base::mint(e, &owner, initial_supply);
4641
e.storage().instance().set(&OWNER, &owner);
4742
}
4843

4944
/// `TokenInterface` doesn't require implementing `total_supply()` because
5045
/// of the need for backwards compatibility with Stellar classic assets.
5146
pub fn total_supply(e: &Env) -> i128 {
52-
fungible::total_supply(e)
47+
Base::total_supply(e)
48+
}
49+
50+
#[when_not_paused]
51+
pub fn mint(e: &Env, account: Address, amount: i128) {
52+
// When `ownable` module is available,
53+
// the following checks should be equivalent to:
54+
// `ownable::only_owner(&e);`
55+
let owner: Address = e.storage().instance().get(&OWNER).expect("owner should be set");
56+
owner.require_auth();
57+
58+
Base::mint(e, &account, amount);
5359
}
5460
}
5561

@@ -63,84 +69,72 @@ impl Pausable for ExampleContract {
6369
// When `ownable` module is available,
6470
// the following checks should be equivalent to:
6571
// `ownable::only_owner(&e);`
72+
caller.require_auth();
6673
let owner: Address = e.storage().instance().get(&OWNER).expect("owner should be set");
6774
if owner != caller {
6875
panic_with_error!(e, ExampleContractError::Unauthorized);
6976
}
7077

71-
pausable::pause(e, &caller);
78+
pausable::pause(e);
7279
}
7380

7481
fn unpause(e: &Env, caller: Address) {
7582
// When `ownable` module is available,
7683
// the following checks should be equivalent to:
7784
// `ownable::only_owner(&e);`
85+
caller.require_auth();
7886
let owner: Address = e.storage().instance().get(&OWNER).expect("owner should be set");
7987
if owner != caller {
8088
panic_with_error!(e, ExampleContractError::Unauthorized);
8189
}
8290

83-
pausable::unpause(e, &caller);
91+
pausable::unpause(e);
8492
}
8593
}
8694

8795
#[contractimpl]
8896
impl TokenInterface for ExampleContract {
8997
fn balance(e: Env, account: Address) -> i128 {
90-
fungible::balance(&e, &account)
98+
Base::balance(&e, &account)
9199
}
92100

93101
fn allowance(e: Env, owner: Address, spender: Address) -> i128 {
94-
fungible::allowance(&e, &owner, &spender)
102+
Base::allowance(&e, &owner, &spender)
95103
}
96104

97105
#[when_not_paused]
98106
fn transfer(e: Env, from: Address, to: Address, amount: i128) {
99-
fungible::transfer(&e, &from, &to, amount);
107+
Base::transfer(&e, &from, &to, amount);
100108
}
101109

102110
#[when_not_paused]
103111
fn transfer_from(e: Env, spender: Address, from: Address, to: Address, amount: i128) {
104-
fungible::transfer_from(&e, &spender, &from, &to, amount);
112+
Base::transfer_from(&e, &spender, &from, &to, amount);
105113
}
106114

107115
fn approve(e: Env, owner: Address, spender: Address, amount: i128, live_until_ledger: u32) {
108-
fungible::approve(&e, &owner, &spender, amount, live_until_ledger);
116+
Base::approve(&e, &owner, &spender, amount, live_until_ledger);
109117
}
110118

111119
#[when_not_paused]
112120
fn burn(e: Env, from: Address, amount: i128) {
113-
fungible::burnable::burn(&e, &from, amount)
121+
Base::burn(&e, &from, amount)
114122
}
115123

116124
#[when_not_paused]
117125
fn burn_from(e: Env, spender: Address, from: Address, amount: i128) {
118-
fungible::burnable::burn_from(&e, &spender, &from, amount)
126+
Base::burn_from(&e, &spender, &from, amount)
119127
}
120128

121129
fn decimals(e: Env) -> u32 {
122-
fungible::metadata::decimals(&e)
130+
Base::decimals(&e)
123131
}
124132

125133
fn name(e: Env) -> String {
126-
fungible::metadata::name(&e)
134+
Base::name(&e)
127135
}
128136

129137
fn symbol(e: Env) -> String {
130-
fungible::metadata::symbol(&e)
131-
}
132-
}
133-
134-
#[contractimpl]
135-
impl FungibleMintable for ExampleContract {
136-
#[when_not_paused]
137-
fn mint(e: &Env, account: Address, amount: i128) {
138-
// When `ownable` module is available,
139-
// the following checks should be equivalent to:
140-
// `ownable::only_owner(&e);`
141-
let owner: Address = e.storage().instance().get(&OWNER).expect("owner should be set");
142-
owner.require_auth();
143-
144-
fungible::mintable::mint(e, &account, amount);
138+
Base::symbol(&e)
145139
}
146140
}

contracts/fungible-token-interface/src/test.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ fn transfer_works() {
3939
}
4040

4141
#[test]
42-
#[should_panic(expected = "Error(Contract, #100)")]
42+
#[should_panic(expected = "Error(Contract, #1000)")]
4343
fn transfer_fails_when_paused() {
4444
let e = Env::default();
4545
let owner = Address::generate(&e);
@@ -67,7 +67,7 @@ fn transfer_from_works() {
6767
}
6868

6969
#[test]
70-
#[should_panic(expected = "Error(Contract, #100)")]
70+
#[should_panic(expected = "Error(Contract, #1000)")]
7171
fn transfer_from_fails_when_paused() {
7272
let e = Env::default();
7373
let owner = Address::generate(&e);
@@ -93,7 +93,7 @@ fn mint_works() {
9393
}
9494

9595
#[test]
96-
#[should_panic(expected = "Error(Contract, #100)")]
96+
#[should_panic(expected = "Error(Contract, #1000)")]
9797
fn mint_fails_when_paused() {
9898
let e = Env::default();
9999
let owner = Address::generate(&e);
@@ -117,7 +117,7 @@ fn burn_works() {
117117
}
118118

119119
#[test]
120-
#[should_panic(expected = "Error(Contract, #100)")]
120+
#[should_panic(expected = "Error(Contract, #1000)")]
121121
fn burn_fails_when_paused() {
122122
let e = Env::default();
123123
let owner = Address::generate(&e);

contracts/hello_world/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[package]
2-
name = "soroban-hello-world-contract"
2+
name = "stellar-hello-world-contract"
33
description = "A simple hello world contract"
44
edition.workspace = true
55
license.workspace = true
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
[package]
2+
name = "nft-enumerable-example"
3+
edition.workspace = true
4+
license.workspace = true
5+
repository.workspace = true
6+
publish = false
7+
version.workspace = true
8+
9+
[lib]
10+
crate-type = ["cdylib"]
11+
doctest = false
12+
13+
[dependencies]
14+
soroban-sdk = { workspace = true }
15+
stellar-non-fungible = { workspace = true }
16+
stellar-default-impl-macro = { workspace = true }
17+
18+
[dev-dependencies]
19+
soroban-sdk = { workspace = true, features = ["testutils"] }

0 commit comments

Comments
 (0)