diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 79281be..dfa831e 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -19,7 +19,7 @@ jobs: - uses: actions/checkout@v3 - run: rustup update ${{ matrix.toolchain }} && rustup default ${{ matrix.toolchain }} - run: rustup target add wasm32-unknown-unknown - - run: cargo install --locked --version 20.0.0-rc2 soroban-cli + - run: cargo install --locked --version 20.1.0 soroban-cli - name: Build contracts run: | soroban contract build diff --git a/CHANGELOG.md b/CHANGELOG.md index ff4578c..c534ee3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 0.14.0 (21.12.2023) +- [Bump `soroban-sdk` to `20.0.0`](https://github.com/kommitters/chaincerts-smart-contracts/issues/160) +- [Extend Instance TTL on initialization to 31 days in ledgers](https://github.com/kommitters/chaincerts-smart-contracts/pull/163) + ## 0.13.0 (07.12.2023) - [Contracts improvements](https://github.com/kommitters/chaincerts-smart-contracts/pull/155) diff --git a/Cargo.toml b/Cargo.toml index 4544ea2..b1eebf4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,13 +4,13 @@ resolver = "2" members = ["deployer_contract", "vault_contract", "vc_issuance_contract"] [workspace.package] -version = "0.13.0" +version = "0.14.0" edition = "2021" license = "Apache-2.0" repository = "https://github.com/kommitters/chaincerts-smart-contracts" [workspace.dependencies] -soroban-sdk = { version = "=20.0.0-rc2.2" } +soroban-sdk = { version = "=20.0.0" } [profile.release] opt-level = "z" diff --git a/deployer_contract/did_contract.wasm b/deployer_contract/did_contract.wasm old mode 100755 new mode 100644 index a4be7d0..df6c263 Binary files a/deployer_contract/did_contract.wasm and b/deployer_contract/did_contract.wasm differ diff --git a/deployer_contract/src/test.rs b/deployer_contract/src/test.rs index 82fdbc9..b4b6831 100644 --- a/deployer_contract/src/test.rs +++ b/deployer_contract/src/test.rs @@ -25,35 +25,32 @@ fn test_from_contract() { // Deploy contract using deployer, and include an init function to call. let salt = BytesN::from_array(&env, &[0; 32]); - let address = Address::random(&env); + let address = Address::generate(&env); let init_args = did_init_args(&env, &address); let (contract_id, init_result) = client.deploy(&client.address, &wasm_id, &salt, &init_args); assert!(init_result.is_void()); let expected_did_document = DIDDocument { - id: String::from_slice(&env, "did:chaincerts:ABC123"), - authentication: vec![ - &env, - String::from_slice(&env, "did:chaincerts:ABC123#key-1"), - ], + id: String::from_str(&env, "did:chaincerts:ABC123"), + authentication: vec![&env, String::from_str(&env, "did:chaincerts:ABC123#key-1")], context: vec![ &env, - String::from_slice(&env, "https://www.w3.org/ns/did/v1"), - String::from_slice(&env, "https://www.example.com/context/v1"), + String::from_str(&env, "https://www.w3.org/ns/did/v1"), + String::from_str(&env, "https://www.example.com/context/v1"), ], services: vec![ &env, Service { - type_: String::from_slice(&env, "VerifiableCredential"), - service_endpoint: String::from_slice(&env, "https://did.chaincerts.co/ABC123"), + type_: String::from_str(&env, "VerifiableCredential"), + service_endpoint: String::from_str(&env, "https://did.chaincerts.co/ABC123"), }, ], verification_method: vec![ &env, VerificationMethod { - id: String::from_slice(&env, "did:chaincerts:ABC123#key-1"), - type_: String::from_slice(&env, "Ed25519VerificationKey2020"), - controller: String::from_slice(&env, "did:chaincerts:ABC123"), + id: String::from_str(&env, "did:chaincerts:ABC123#key-1"), + type_: String::from_str(&env, "Ed25519VerificationKey2020"), + controller: String::from_str(&env, "did:chaincerts:ABC123"), blockchain_account_id: address, }, ], @@ -76,11 +73,11 @@ fn test_deploy_from_address() { let wasm_hash = env.deployer().upload_contract_wasm(contract::WASM); // Define a deployer address that needs to authorize the deployment. - let deployer = Address::random(&env); + let deployer = Address::generate(&env); // Deploy contract using deployer, and include an init function to call. let salt = BytesN::from_array(&env, &[0; 32]); - let address = Address::random(&env); + let address = Address::generate(&env); let init_fn_args = did_init_args(&env, &address); env.mock_all_auths(); let (contract_id, init_result) = @@ -89,29 +86,26 @@ fn test_deploy_from_address() { assert!(init_result.is_void()); let expected_did_document = DIDDocument { - id: String::from_slice(&env, "did:chaincerts:ABC123"), - authentication: vec![ - &env, - String::from_slice(&env, "did:chaincerts:ABC123#key-1"), - ], + id: String::from_str(&env, "did:chaincerts:ABC123"), + authentication: vec![&env, String::from_str(&env, "did:chaincerts:ABC123#key-1")], context: vec![ &env, - String::from_slice(&env, "https://www.w3.org/ns/did/v1"), - String::from_slice(&env, "https://www.example.com/context/v1"), + String::from_str(&env, "https://www.w3.org/ns/did/v1"), + String::from_str(&env, "https://www.example.com/context/v1"), ], services: vec![ &env, Service { - type_: String::from_slice(&env, "VerifiableCredential"), - service_endpoint: String::from_slice(&env, "https://did.chaincerts.co/ABC123"), + type_: String::from_str(&env, "VerifiableCredential"), + service_endpoint: String::from_str(&env, "https://did.chaincerts.co/ABC123"), }, ], verification_method: vec![ &env, VerificationMethod { - id: String::from_slice(&env, "did:chaincerts:ABC123#key-1"), - type_: String::from_slice(&env, "Ed25519VerificationKey2020"), - controller: String::from_slice(&env, "did:chaincerts:ABC123"), + id: String::from_str(&env, "did:chaincerts:ABC123#key-1"), + type_: String::from_str(&env, "Ed25519VerificationKey2020"), + controller: String::from_str(&env, "did:chaincerts:ABC123"), blockchain_account_id: address, }, ], @@ -124,26 +118,26 @@ fn test_deploy_from_address() { } fn did_init_args(env: &Env, address: &Address) -> Vec { - let id = String::from_slice(env, "did:chaincerts:ABC123"); + let id = String::from_str(env, "did:chaincerts:ABC123"); let authentication_params = ( - String::from_slice(env, "did:chaincerts:ABC123#key-1"), + String::from_str(env, "did:chaincerts:ABC123#key-1"), address, ); let context = vec![ env, - String::from_slice(env, "https://www.w3.org/ns/did/v1"), - String::from_slice(env, "https://www.example.com/context/v1"), + String::from_str(env, "https://www.w3.org/ns/did/v1"), + String::from_str(env, "https://www.example.com/context/v1"), ]; let method = Method { - type_: String::from_slice(env, "otp"), + type_: String::from_str(env, "otp"), verified: true, timestamp: 1684872059, service: OptionMethodService::None, }; let verification_processes = vec![env, method]; let service = Service { - type_: String::from_slice(env, "VerifiableCredential"), - service_endpoint: String::from_slice(env, "https://did.chaincerts.co/ABC123"), + type_: String::from_str(env, "VerifiableCredential"), + service_endpoint: String::from_str(env, "https://did.chaincerts.co/ABC123"), }; let services = vec![env, service]; let public_add_cap: Option = Option::None; diff --git a/did_contract b/did_contract index e353d8a..6eb7599 160000 --- a/did_contract +++ b/did_contract @@ -1 +1 @@ -Subproject commit e353d8a1ca52f458d5fa55802295398aff39ccdd +Subproject commit 6eb75997c422bd979185d89d421ae6b8ae8ca9e3 diff --git a/vault_contract/src/contract.rs b/vault_contract/src/contract.rs index 89328ff..1c55e1c 100644 --- a/vault_contract/src/contract.rs +++ b/vault_contract/src/contract.rs @@ -10,8 +10,10 @@ use soroban_sdk::{ contract, contractimpl, contractmeta, panic_with_error, Address, Env, IntoVal, Map, String, Vec, }; -const LEDGERS_THRESHOLD: u32 = 1; -const LEDGERS_TO_EXTEND: u32 = 535_000; +// MAXIMUM ENTRY TTL: +// 31 days, 12 ledger close per minute. +// (12 * 60 * 24 * 31) - 1 +const LEDGERS_TO_EXTEND: u32 = 535_679; contractmeta!( key = "Description", @@ -33,7 +35,7 @@ impl VaultTrait for VaultContract { e.storage() .instance() - .bump(LEDGERS_THRESHOLD, LEDGERS_TO_EXTEND); + .extend_ttl(LEDGERS_TO_EXTEND, LEDGERS_TO_EXTEND); } fn authorize_issuer(e: Env, admin: Address, issuer: Address, did: String) { diff --git a/vault_contract/src/test/contract.rs b/vault_contract/src/test/contract.rs index cb02b54..088a335 100644 --- a/vault_contract/src/test/contract.rs +++ b/vault_contract/src/test/contract.rs @@ -75,7 +75,7 @@ fn test_authorize_issuer_with_invalid_admin() { contract, } = VaultContractTest::setup(); - let invalid_admin = Address::random(&env); + let invalid_admin = Address::generate(&env); contract.initialize(&admin, &dids); contract.authorize_issuer(&invalid_admin, &issuer, &did); @@ -93,7 +93,7 @@ fn test_authorize_issuer_with_not_registered_vault() { contract, } = VaultContractTest::setup(); contract.initialize(&admin, &dids); - let invalid_did = String::from_slice(&env, "did:chaincerts:3mtjfbxad3wzh7qa4w5f7q4h"); + let invalid_did = String::from_str(&env, "did:chaincerts:3mtjfbxad3wzh7qa4w5f7q4h"); contract.authorize_issuer(&admin, &issuer, &invalid_did); } @@ -146,7 +146,7 @@ fn test_revoke_issuer_with_invalid_admin() { contract.initialize(&admin, &dids); contract.authorize_issuer(&admin, &issuer, &did); - let invalid_admin = Address::random(&env); + let invalid_admin = Address::generate(&env); contract.revoke_issuer(&invalid_admin, &issuer, &did); } @@ -165,7 +165,7 @@ fn test_revoke_issuer_when_issuer_is_not_found() { contract.initialize(&admin, &dids); contract.authorize_issuer(&admin, &issuer, &did); - let invalid_issuer = Address::random(&env); + let invalid_issuer = Address::generate(&env); contract.revoke_issuer(&admin, &invalid_issuer, &did); } @@ -181,7 +181,7 @@ fn test_revoke_issuer_with_not_registered_did() { contract, } = VaultContractTest::setup(); contract.initialize(&admin, &dids); - let invalid_did = String::from_slice(&env, "did:chaincerts:3mtjfbxad3wzh7qa4w5f7q4h"); + let invalid_did = String::from_str(&env, "did:chaincerts:3mtjfbxad3wzh7qa4w5f7q4h"); contract.revoke_issuer(&admin, &issuer, &invalid_did); } @@ -259,7 +259,7 @@ fn test_store_vc_with_issuer_not_found() { contract, } = VaultContractTest::setup(); - let invalid_issuer = Address::random(&env); + let invalid_issuer = Address::generate(&env); let VCVaultContractTest { vc_id, @@ -314,7 +314,7 @@ fn test_store_vc_with_vault_not_found() { issuer, contract, } = VaultContractTest::setup(); - let invalid_did = String::from_slice(&env, "did:chaincerts:3mtjfbxad3wzh7qa4w5f7q4h"); + let invalid_did = String::from_str(&env, "did:chaincerts:3mtjfbxad3wzh7qa4w5f7q4h"); let VCVaultContractTest { vc_id, @@ -348,7 +348,7 @@ fn test_get_vault_not_found() { contract.initialize(&admin, &dids); - let bad_vault_did: String = String::from_slice(&env, "did:chaincerts:xyz123"); + let bad_vault_did: String = String::from_str(&env, "did:chaincerts:xyz123"); contract.get_vault(&bad_vault_did); } @@ -384,9 +384,9 @@ fn test_list_vaults() { issuance_contract_address, } = get_vc_setup(&env); - let vc_id2 = String::from_slice(&env, "vc_id2"); - let vc_id3 = String::from_slice(&env, "vc_id3"); - let did2 = String::from_slice(&env, "did:chaincerts:3mtjfbxad3wzh7qa4w5f7q4h"); + let vc_id2 = String::from_str(&env, "vc_id2"); + let vc_id3 = String::from_str(&env, "vc_id3"); + let did2 = String::from_str(&env, "did:chaincerts:3mtjfbxad3wzh7qa4w5f7q4h"); let dids = vec![&env, did.clone(), did2.clone()]; contract.initialize(&admin, &dids); @@ -427,7 +427,7 @@ fn test_register_vault() { issuer: _, contract, } = VaultContractTest::setup(); - let did2 = String::from_slice(&env, "did:chaincerts:3mtjfbxad3wzh7qa4w5f7q4h"); + let did2 = String::from_str(&env, "did:chaincerts:3mtjfbxad3wzh7qa4w5f7q4h"); contract.initialize(&admin, &dids); contract.register_vault(&admin, &did2); @@ -460,8 +460,8 @@ fn test_register_vault_with_invalid_admin() { issuer: _, contract, } = VaultContractTest::setup(); - let did2 = String::from_slice(&env, "did:chaincerts:3mtjfbxad3wzh7qa4w5f7q4h"); - let invalid_admin = Address::random(&env); + let did2 = String::from_str(&env, "did:chaincerts:3mtjfbxad3wzh7qa4w5f7q4h"); + let invalid_admin = Address::generate(&env); contract.initialize(&admin, &dids); contract.register_vault(&invalid_admin, &did2); @@ -493,7 +493,7 @@ fn test_revoke_vault_with_invalid_admin() { issuer: _, contract, } = VaultContractTest::setup(); - let invalid_admin = Address::random(&env); + let invalid_admin = Address::generate(&env); contract.initialize(&admin, &dids); contract.revoke_vault(&invalid_admin, &did); @@ -510,7 +510,7 @@ fn test_revoke_vault_with_no_registered_did() { issuer: _, contract, } = VaultContractTest::setup(); - let invalid_did = String::from_slice(&env, "did:chaincerts:3mtjfbxad3wzh7qa4w5f7q4h"); + let invalid_did = String::from_str(&env, "did:chaincerts:3mtjfbxad3wzh7qa4w5f7q4h"); contract.initialize(&admin, &dids); contract.revoke_vault(&admin, &invalid_did); diff --git a/vault_contract/src/test/setup.rs b/vault_contract/src/test/setup.rs index f5930c3..bdaa836 100644 --- a/vault_contract/src/test/setup.rs +++ b/vault_contract/src/test/setup.rs @@ -14,10 +14,10 @@ impl<'a> VaultContractTest<'a> { pub fn setup() -> Self { let env: Env = Default::default(); env.mock_all_auths(); - let admin = Address::random(&env); - let did = String::from_slice(&env, "did:chaincerts:5ppl9sm47frl0tpj7g3lp6eo"); + let admin = Address::generate(&env); + let did = String::from_str(&env, "did:chaincerts:5ppl9sm47frl0tpj7g3lp6eo"); let dids = vec![&env, did.clone()]; - let issuer = Address::random(&env); + let issuer = Address::generate(&env); let contract = VaultContractClient::new(&env, &env.register_contract(None, VaultContract)); VaultContractTest { @@ -38,9 +38,9 @@ pub struct VCVaultContractTest { } pub fn get_vc_setup(env: &Env) -> VCVaultContractTest { - let vc_id = String::from_slice(env, "vc_id"); - let vc_data = String::from_slice(env, "vc_data"); - let issuance_contract_address = Address::random(env); + let vc_id = String::from_str(env, "vc_id"); + let vc_data = String::from_str(env, "vc_data"); + let issuance_contract_address = Address::generate(env); VCVaultContractTest { vc_id, diff --git a/vc_issuance_contract/src/contract.rs b/vc_issuance_contract/src/contract.rs index 049a0b6..e329ede 100644 --- a/vc_issuance_contract/src/contract.rs +++ b/vc_issuance_contract/src/contract.rs @@ -8,8 +8,10 @@ use soroban_sdk::{ contract, contractimpl, contractmeta, map, panic_with_error, Address, Env, Map, String, Vec, }; -const LEDGERS_THRESHOLD: u32 = 1; -const LEDGERS_TO_EXTEND: u32 = 535_000; +// MAXIMUM ENTRY TTL: +// 31 days, 12 ledger close per minute. +// (12 * 60 * 24 * 31) - 1 +const LEDGERS_TO_EXTEND: u32 = 535_679; const DEFAULT_AMOUNT: u32 = 20; const MAX_AMOUNT: u32 = 100; @@ -40,7 +42,7 @@ impl VCIssuanceTrait for VCIssuanceContract { e.storage() .instance() - .bump(LEDGERS_THRESHOLD, LEDGERS_TO_EXTEND); + .extend_ttl(LEDGERS_TO_EXTEND, LEDGERS_TO_EXTEND); } fn issue( e: Env, @@ -68,10 +70,10 @@ impl VCIssuanceTrait for VCIssuanceContract { validate_vc(&e, &vc_id); let revocations = storage::read_vcs_revocations(&e); - let status_str = String::from_slice(&e, "status"); - let since_str = String::from_slice(&e, "since"); - let revoked_str = String::from_slice(&e, "revoked"); - let valid_str = String::from_slice(&e, "valid"); + let status_str = String::from_str(&e, "status"); + let since_str = String::from_str(&e, "since"); + let revoked_str = String::from_str(&e, "revoked"); + let valid_str = String::from_str(&e, "valid"); match revocations.get(vc_id) { Some(revocation) => map![&e, (status_str, revoked_str), (since_str, revocation.date)], diff --git a/vc_issuance_contract/src/test/contract.rs b/vc_issuance_contract/src/test/contract.rs index 62cdc8b..c2a5ee8 100644 --- a/vc_issuance_contract/src/test/contract.rs +++ b/vc_issuance_contract/src/test/contract.rs @@ -87,7 +87,7 @@ fn test_issue_with_invalid_admin() { recipient_did, contract, } = VCIssuanceContractTest::setup(); - let invalid_admin = Address::random(&env); + let invalid_admin = Address::generate(&env); let vault_contract_id = create_vc(&env, &admin, &contract, &recipient_did, &None); contract.issue(&invalid_admin, &vc_data, &recipient_did, &vault_contract_id); @@ -122,8 +122,8 @@ fn test_revoke_vc_with_invalid_vc() { } = VCIssuanceContractTest::setup(); contract.initialize(&admin, &Some(10)); - let vc_id = String::from_slice(&env, "vc_id1"); - let date = String::from_slice(&env, "2023-12-05T21:37:44.389Z"); + let vc_id = String::from_str(&env, "vc_id1"); + let date = String::from_str(&env, "2023-12-05T21:37:44.389Z"); contract.revoke(&admin, &vc_id, &date); } @@ -141,7 +141,7 @@ fn test_revoke_vc() { let vault_contract_id = create_vc(&env, &admin, &contract, &recipient_did, &None); let vc_id = contract.issue(&admin, &vc_data, &recipient_did, &vault_contract_id); - let date = String::from_slice(&env, "2023-12-05T21:37:44.389Z"); + let date = String::from_str(&env, "2023-12-05T21:37:44.389Z"); contract.revoke(&admin, &vc_id, &date); } @@ -175,7 +175,7 @@ fn test_verify_vc_with_revoked_vc() { } = VCIssuanceContractTest::setup(); let vault_contract_id = create_vc(&env, &admin, &contract, &recipient_did, &None); let vc_id = contract.issue(&admin, &vc_data, &recipient_did, &vault_contract_id); - let date = String::from_slice(&env, "2023-12-05T21:37:44.389Z"); + let date = String::from_str(&env, "2023-12-05T21:37:44.389Z"); contract.revoke(&admin, &vc_id, &date); diff --git a/vc_issuance_contract/src/test/setup.rs b/vc_issuance_contract/src/test/setup.rs index 4edd127..c74e5e3 100644 --- a/vc_issuance_contract/src/test/setup.rs +++ b/vc_issuance_contract/src/test/setup.rs @@ -15,12 +15,12 @@ impl<'a> VCIssuanceContractTest<'a> { pub fn setup() -> Self { let env: Env = Default::default(); env.mock_all_auths(); - let admin = Address::random(&env); + let admin = Address::generate(&env); let contract = VCIssuanceContractClient::new(&env, &env.register_contract(None, VCIssuanceContract)); let amount = Some(10); - let vc_data = String::from_slice(&env, "eoZXggNeVDW2g5GeA0G2s0QJBn3SZWzWSE3fXM9V6IB5wWIfFJRxPrTLQRMHulCF62bVQNmZkj7zbSa39fVjAUTtfm6JMio75uMxoDlAN/Y"); - let recipient_did = String::from_slice(&env, "did:chaincerts:pe4t2r94dftr1n1gf6jikt6a"); + let vc_data = String::from_str(&env, "eoZXggNeVDW2g5GeA0G2s0QJBn3SZWzWSE3fXM9V6IB5wWIfFJRxPrTLQRMHulCF62bVQNmZkj7zbSa39fVjAUTtfm6JMio75uMxoDlAN/Y"); + let recipient_did = String::from_str(&env, "did:chaincerts:pe4t2r94dftr1n1gf6jikt6a"); VCIssuanceContractTest { env, @@ -40,7 +40,7 @@ pub fn create_vc( recipient_did: &String, amount: &Option, ) -> Address { - let vault_admin = Address::random(env); + let vault_admin = Address::generate(env); let vault_contract_id = env.register_contract_wasm(None, vault_contract::WASM); let vault_client = vault_contract::Client::new(env, &vault_contract_id); @@ -54,16 +54,16 @@ pub fn create_vc( } pub fn get_revoked_vc_map(env: &Env, date: String) -> Map { - let status_str = String::from_slice(env, "status"); - let since_str = String::from_slice(env, "since"); - let revoked_str = String::from_slice(env, "revoked"); + let status_str = String::from_str(env, "status"); + let since_str = String::from_str(env, "since"); + let revoked_str = String::from_str(env, "revoked"); map![env, (status_str, revoked_str), (since_str, date)] } pub fn get_valid_vc_map(env: &Env) -> Map { - let status_str = String::from_slice(env, "status"); - let valid_str = String::from_slice(env, "valid"); + let status_str = String::from_str(env, "status"); + let valid_str = String::from_str(env, "valid"); map![env, (status_str, valid_str)] } diff --git a/vc_issuance_contract/src/verifiable_credential.rs b/vc_issuance_contract/src/verifiable_credential.rs index ce27164..6223051 100644 --- a/vc_issuance_contract/src/verifiable_credential.rs +++ b/vc_issuance_contract/src/verifiable_credential.rs @@ -17,14 +17,15 @@ pub fn generate_id(e: &Env) -> String { let str_id = core::str::from_utf8(id.as_ref()).unwrap(); - String::from_slice(e, str_id) + String::from_str(e, str_id) } fn get_random_bytes(e: &Env) -> [u8; 15] { let mut random_bytes = [0u8; 15]; for byte in &mut random_bytes { - *byte = e.prng().u64_in_range(0..256) as u8; + let rand_number: u64 = e.prng().gen_range(0..256); + *byte = rand_number as u8; } random_bytes