From 73281b51f546454eec8d9ed035cd5b592e08e971 Mon Sep 17 00:00:00 2001 From: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com> Date: Fri, 2 Dec 2022 17:03:40 -0800 Subject: [PATCH] Remove BigInt and replace with i128 --- docs/built-in-contracts/token.mdx | 36 +++++++++++----------- docs/common-interfaces/token.mdx | 32 +++++++++---------- docs/examples/auth-advanced.mdx | 48 +++++++++++++---------------- docs/examples/hello-world.mdx | 4 +-- docs/learn/built-in-types.mdx | 12 +++----- docs/sdks/byo.mdx | 2 -- docs/tutorials/write-a-contract.mdx | 4 +-- 7 files changed, 63 insertions(+), 75 deletions(-) diff --git a/docs/built-in-contracts/token.mdx b/docs/built-in-contracts/token.mdx index a5603318..d5949738 100644 --- a/docs/built-in-contracts/token.mdx +++ b/docs/built-in-contracts/token.mdx @@ -87,9 +87,9 @@ token.with_source_account(&token_admin_id).mint( // `token_admin_id` in this case. &Signature::Invoker, // Nonce is always 0 for invokers. - &BigInt::zero(&env), + &0, &user_id, - &BigInt::from_u32(&env, 1000), + &1000, ); ``` @@ -117,14 +117,14 @@ let sig = soroban_auth::testutils::ed25519::sign( // Arguments of the contract function call. // Notice that instead of the signature (first `mint` argument), public key // is used as the first argument here. - (&token_admin_id, &nonce, &user_id, &BigInt::from_u32(&env, 1000)), + (&token_admin_id, &nonce, &user_id, &1000), ); // Call the contract with signature we computed above. token.mint( &sig, &nonce, &user_id, - &BigInt::from_u32(&env, 1000), + &1000, ); ``` @@ -172,60 +172,60 @@ fn init(env: Env, admin: Identifier, metadata: TokenMetadata); // user. // `id` must be a classic Stellar account (i.e. an account invoker or signature // signed by an account). -fn import(env: Env, id: Signature, nonce: BigInt, amount: i64); +fn import(env: Env, id: Signature, nonce: i128, amount: i64); // Moves the `amount` from token balance to the classic asset balance of `id` // user. // `id` must be a classic Stellar account (i.e. an account invoker or signature // signed by an account). -fn export(env: Env, id: Signature, nonce: BigInt, amount: i64); +fn export(env: Env, id: Signature, nonce: i128, amount: i64); // 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); +fn burn(e: Env, admin: Signature, nonce: i128, from: Identifier, amount: i128); // If "admin" is the administrator, mint "amount" to "to" -fn mint(e: Env, admin: Signature, nonce: BigInt, to: Identifier, amount: BigInt); +fn mint(e: Env, admin: Signature, nonce: i128, to: Identifier, amount: i128); // If "admin" is the administrator, set the administrator to "id" -fn set_admin(e: Env, admin: Signature, nonce: BigInt, new_admin: Identifier); +fn set_admin(e: Env, admin: Signature, nonce: i128, new_admin: Identifier); // If "admin" is the administrator, freeze "id" -fn freeze(e: Env, admin: Signature, nonce: BigInt, id: Identifier); +fn freeze(e: Env, admin: Signature, nonce: i128, id: Identifier); // If "admin" is the administrator, unfreeze "id" -fn unfreeze(e: Env, admin: Signature, nonce: BigInt, id: Identifier); +fn unfreeze(e: Env, admin: Signature, nonce: i128, id: Identifier); // Token Interface // Get the allowance for "spender" to transfer from "from" -fn allowance(e: Env, from: Identifier, spender: Identifier) -> BigInt; +fn allowance(e: Env, from: Identifier, spender: Identifier) -> i128; // Set the allowance to "amount" for "spender" to transfer from "from" -fn approve(e: Env, from: Signature, nonce: BigInt, spender: Identifier, amount: BigInt); +fn approve(e: Env, from: Signature, nonce: i128, spender: Identifier, amount: i128); // Get the balance of "id" -fn balance(e: Env, id: Identifier) -> BigInt; +fn balance(e: Env, id: Identifier) -> i128; // Transfer "amount" from "from" to "to" -fn xfer(e: Env, from: Signature, nonce: BigInt, to: Identifier, amount: BigInt); +fn xfer(e: Env, from: Signature, nonce: i128, to: Identifier, amount: i128); // Transfer "amount" from "from" to "to", consuming the allowance of "spender" fn xfer_from( e: Env, spender: Signature, - nonce: BigInt, + nonce: i128, from: Identifier, to: Identifier, - amount: BigInt, + amount: i128, ); // 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; +fn nonce(e: Env, id: Identifier) -> i128; // Descriptive Interface diff --git a/docs/common-interfaces/token.mdx b/docs/common-interfaces/token.mdx index 21db6198..0aad4e3b 100644 --- a/docs/common-interfaces/token.mdx +++ b/docs/common-interfaces/token.mdx @@ -23,25 +23,25 @@ pub trait Contract { fn burn( env: soroban_sdk::Env, admin: soroban_auth::Signature, - nonce: soroban_sdk::BigInt, + nonce: soroban_sdk::i128, from: soroban_auth::Identifier, - amount: soroban_sdk::BigInt, + amount: soroban_sdk::i128, ); /// If "admin" is the administrator, mint "amount" to "to". fn mint( env: soroban_sdk::Env, admin: soroban_auth::Signature, - nonce: soroban_sdk::BigInt, + nonce: soroban_sdk::i128, to: soroban_auth::Identifier, - amount: soroban_sdk::BigInt, + amount: soroban_sdk::i128, ); /// If "admin" is the administrator, set the administrator to "id". fn set_admin( env: soroban_sdk::Env, admin: soroban_auth::Signature, - nonce: soroban_sdk::BigInt, + nonce: soroban_sdk::i128, new_admin: soroban_auth::Identifier, ); @@ -49,7 +49,7 @@ pub trait Contract { fn freeze( env: soroban_sdk::Env, admin: soroban_auth::Signature, - nonce: soroban_sdk::BigInt, + nonce: soroban_sdk::i128, id: soroban_auth::Identifier, ); @@ -57,7 +57,7 @@ pub trait Contract { fn unfreeze( env: soroban_sdk::Env, admin: soroban_auth::Signature, - nonce: soroban_sdk::BigInt, + nonce: soroban_sdk::i128, id: soroban_auth::Identifier, ); @@ -70,44 +70,44 @@ pub trait Contract { env: soroban_sdk::Env, from: soroban_auth::Identifier, spender: soroban_auth::Identifier, - ) -> soroban_sdk::BigInt; + ) -> soroban_sdk::i128; /// Set the allowance to "amount" for "spender" to transfer from "from". fn approve( env: soroban_sdk::Env, from: soroban_auth::Signature, - nonce: soroban_sdk::BigInt, + nonce: soroban_sdk::i128, spender: soroban_auth::Identifier, - amount: soroban_sdk::BigInt, + amount: soroban_sdk::i128, ); /// Get the balance of "id". - fn balance(env: soroban_sdk::Env, id: soroban_auth::Identifier) -> soroban_sdk::BigInt; + fn balance(env: soroban_sdk::Env, id: soroban_auth::Identifier) -> soroban_sdk::i128; /// Transfer "amount" from "from" to "to. fn xfer( env: soroban_sdk::Env, from: soroban_auth::Signature, - nonce: soroban_sdk::BigInt, + nonce: soroban_sdk::i128, to: soroban_auth::Identifier, - amount: soroban_sdk::BigInt, + amount: soroban_sdk::i128, ); /// Transfer "amount" from "from" to "to", consuming the allowance of "spender". fn xfer_from( env: soroban_sdk::Env, spender: soroban_auth::Signature, - nonce: soroban_sdk::BigInt, + nonce: soroban_sdk::i128, from: soroban_auth::Identifier, to: soroban_auth::Identifier, - amount: soroban_sdk::BigInt, + amount: soroban_sdk::i128, ); // Returns true if "id" is frozen. fn is_frozen(env: soroban_sdk::Env, id: soroban_auth::Identifier) -> bool; // Returns the current nonce for "id". - fn nonce(env: soroban_sdk::Env, id: soroban_auth::Identifier) -> soroban_sdk::BigInt; + fn nonce(env: soroban_sdk::Env, id: soroban_auth::Identifier) -> soroban_sdk::i128; // -------------------------------------------------------------------------------- // Descriptive Interface diff --git a/docs/examples/auth-advanced.mdx b/docs/examples/auth-advanced.mdx index 3b558125..ae603279 100644 --- a/docs/examples/auth-advanced.mdx +++ b/docs/examples/auth-advanced.mdx @@ -134,14 +134,14 @@ pub struct IncrementContract; #[contractimpl] impl IncrementContract { /// Increment increments a counter for the invoker, and returns the value. - pub fn increment(env: Env, sig: Signature, nonce: BigInt) -> u32 { + pub fn increment(env: Env, sig: Signature, nonce: i128) -> u32 { // Verify that the signature signs and authorizes this invocation. let id = sig.identifier(&env); verify(&env, &sig, symbol!("increment"), (&id, &nonce)); // Verify that the nonce has not been consumed to prevent replay of the // same presigned invocation more than once. - verify_and_consume_nonce(&env, &sig, &nonce); + verify_and_consume_nonce(&env, &sig, nonce); // Construct a key for the data being stored. Use an enum to set the // contract up well for adding other types of data to be stored. @@ -164,21 +164,21 @@ impl IncrementContract { count } - pub fn nonce(env: Env, id: Identifier) -> BigInt { + pub fn nonce(env: Env, id: Identifier) -> i128 { get_nonce(&env, &id) } } -fn verify_and_consume_nonce(env: &Env, sig: &Signature, nonce: &BigInt) { +fn verify_and_consume_nonce(env: &Env, sig: &Signature, nonce: i128) { match sig { Signature::Invoker => { - if BigInt::zero(env) != nonce { + if nonce != 0 { panic_with_error!(env, Error::IncorrectNonceForInvoker); } } Signature::Ed25519(_) | Signature::Account(_) => { let id = sig.identifier(env); - if nonce != &get_nonce(env, &id) { + if nonce != get_nonce(env, &id) { panic_with_error!(env, Error::IncorrectNonce); } set_nonce(env, &id, nonce + 1); @@ -186,15 +186,12 @@ fn verify_and_consume_nonce(env: &Env, sig: &Signature, nonce: &BigInt) { } } -fn get_nonce(env: &Env, id: &Identifier) -> BigInt { +fn get_nonce(env: &Env, id: &Identifier) -> i128 { let key = DataKey::Nonce(id.clone()); - env.data() - .get(key) - .unwrap_or_else(|| Ok(BigInt::zero(env))) - .unwrap() + env.data().get(key).unwrap_or(Ok(0)).unwrap() } -fn set_nonce(env: &Env, id: &Identifier, nonce: BigInt) { +fn set_nonce(env: &Env, id: &Identifier, nonce: i128) { let key = DataKey::Nonce(id.clone()); env.data().set(key, nonce); } @@ -349,7 +346,7 @@ stored with key `DataKey::Counter`. The `soroban_auth::verify` method verifies the input `Signature`. ```rust -pub fn increment(env: Env, sig: Signature, nonce: BigInt) -> u32 { +pub fn increment(env: Env, sig: Signature, nonce: i128) -> u32 { let id = sig.identifier(&env); verify(&env, &sig, symbol!("increment"), (&id, &nonce)); // ... @@ -397,7 +394,7 @@ This example uses a sequential nonce for replay prevention. ::: ```rust -pub fn increment(env: Env, sig: Signature, nonce: BigInt) -> u32 { +pub fn increment(env: Env, sig: Signature, nonce: i128) -> u32 { // ... verify_and_consume_nonce(&env, &sig, &nonce); // ... @@ -417,16 +414,16 @@ it matches the nonce included in this invocation, and error if not. The nonce is incremented so that the value is consumed and cannot be reused. ```rust -fn verify_and_consume_nonce(env: &Env, sig: &Signature, nonce: &BigInt) { +fn verify_and_consume_nonce(env: &Env, sig: &Signature, nonce: i128) { match sig { Signature::Invoker => { - if BigInt::zero(env) != nonce { + if nonce != 0 { panic_with_error!(env, Error::IncorrectNonceForInvoker); } } Signature::Ed25519(_) | Signature::Account(_) => { let id = sig.identifier(env); - if nonce != &get_nonce(env, &id) { + if nonce != get_nonce(env, &id) { panic_with_error!(env, Error::IncorrectNonce); } set_nonce(env, &id, nonce + 1); @@ -434,15 +431,12 @@ fn verify_and_consume_nonce(env: &Env, sig: &Signature, nonce: &BigInt) { } } -fn get_nonce(env: &Env, id: &Identifier) -> BigInt { +fn get_nonce(env: &Env, id: &Identifier) -> i128 { let key = DataKey::Nonce(id.clone()); - env.data() - .get(key) - .unwrap_or_else(|| Ok(BigInt::zero(env))) - .unwrap() + env.data().get(key).unwrap_or(Ok(0)).unwrap() } -fn set_nonce(env: &Env, id: &Identifier, nonce: BigInt) { +fn set_nonce(env: &Env, id: &Identifier, nonce: i128) { let key = DataKey::Nonce(id.clone()); env.data().set(key, nonce); } @@ -488,7 +482,7 @@ expect users to keep track of the next nonce to use, but that may not be trivial, so the contract exports a function that provides the information. ```rust -pub fn nonce(env: Env, id: Identifier) -> BigInt { +pub fn nonce(env: Env, id: Identifier) -> i128 { get_nonce(&env, &id) } ``` @@ -515,7 +509,7 @@ fn test_auth_with_invoker() { assert_eq!( client .with_source_account(&user_1) - .increment(&Signature::Invoker, &BigInt::zero(&env)), + .increment(&Signature::Invoker, &0), 1 ); // ... @@ -538,7 +532,7 @@ very simple. ```rust client .with_source_account(&user_1) - .increment(&Signature::Invoker, &BigInt::zero(&env)), + .increment(&Signature::Invoker, &0), ``` :::tip @@ -564,7 +558,7 @@ fn test_auth_with_ed25519() { let (user_1_id, user_1_sign) = soroban_auth::testutils::ed25519::generate(&env); let (user_2_id, user_2_sign) = soroban_auth::testutils::ed25519::generate(&env); - let nonce = BigInt::from_u32(&env, 0); + let nonce = 0; let sig = soroban_auth::testutils::ed25519::sign( &env, &user_1_sign, diff --git a/docs/examples/hello-world.mdx b/docs/examples/hello-world.mdx index f609ee43..fd56138a 100644 --- a/docs/examples/hello-world.mdx +++ b/docs/examples/hello-world.mdx @@ -79,8 +79,8 @@ pub struct HelloContract; Contract functions look much like regular Rust functions. They mave have any number of arguments, but arguments must support being transmitted to and from the Soroban environment that the contract runs in. The Soroban SDK provides some -types like `Vec`, `Map`, `BigInt`, `Symbol`, `Bytes`, `BytesN`, etc that -can be used. Primitive values like `u64`, `i64`, `u32`, `i32`, and `bool` can +types like `Vec`, `Map`, `Symbol`, `Bytes`, `BytesN`, etc that can be used. +Primitive values like `u128`, `i128`, `u64`, `i64`, `u32`, `i32`, and `bool` can also be used. Floats are not supported. Contract inputs must not be references. diff --git a/docs/learn/built-in-types.mdx b/docs/learn/built-in-types.mdx index fec3e74d..a98c3828 100644 --- a/docs/learn/built-in-types.mdx +++ b/docs/learn/built-in-types.mdx @@ -27,6 +27,10 @@ The following primitive types are supported: ### Signed 64-bit Integer (`i64`) +### Unsigned 128-bit Integer (`u128`) + +### Signed 128-bit Integer (`i128`) + ### Bool (`bool`) ## Symbol (`Symbol`) @@ -77,14 +81,6 @@ will fail if they are not. Most functions on Map return a Result due to this. Maps have at most one entry per key. Setting a value for a key in the map that already has a value for that key replaces the value. -## BigInt (`BigInt`) - -BigInt is an arbitrary sized signed integer. - -The value is stored in the Host and available to the Guest through functions on -the type. Operations between BigInts are performed inside the Host and do not -consume Guest resources such as memory. - ## Address (`Address`) Address is union of all the types that can be the invoker of a contract. diff --git a/docs/sdks/byo.mdx b/docs/sdks/byo.mdx index 7ffb5c0c..f02ee6b1 100644 --- a/docs/sdks/byo.mdx +++ b/docs/sdks/byo.mdx @@ -47,7 +47,6 @@ guarantee exists at this time. - [Map] - [Vec] - [Bytes] - - [BigInt] ### User Defined Types @@ -114,6 +113,5 @@ The test environment should include: [Map]: https://github.com/stellar/rs-soroban-sdk/blob/main/soroban-sdk/src/map.rs [Vec]: https://github.com/stellar/rs-soroban-sdk/blob/main/soroban-sdk/src/vec.rs [Bytes]: https://github.com/stellar/rs-soroban-sdk/blob/main/soroban-sdk/src/bytes.rs -[BigInt]: https://github.com/stellar/rs-soroban-sdk/blob/main/soroban-sdk/src/bigint.rs [`SCEnvMetaEntry`]: https://github.com/stellar/stellar-xdr/blob/next/Stellar-contract-env-meta.x [`SCSpecEntry`]: https://github.com/stellar/stellar-xdr/blob/next/Stellar-contract-spec.x diff --git a/docs/tutorials/write-a-contract.mdx b/docs/tutorials/write-a-contract.mdx index b617e3a6..6a2dbe15 100644 --- a/docs/tutorials/write-a-contract.mdx +++ b/docs/tutorials/write-a-contract.mdx @@ -26,8 +26,8 @@ how to setup a project. Many of the types available in typical Rust programs, such as `std::vec::Vec`, are not available, as there is no allocator and no heap memory in Soroban contracts. The `soroban-sdk` provides a variety of types like `Vec`, `Map`, -`BigInt`, `Bytes`, `BytesN`, `Symbol`, that all utilize the Soroban -environment's memory and native capabilities. +`Bytes`, `BytesN`, `Symbol`, that all utilize the Soroban environment's memory +and native capabilities. ```rust pub struct Contract;