sui_derivable_account - [devnet]
Esta página aún no está disponible en tu idioma.
Derivable account abstraction that verifies a message signed by Sui wallet.
- The message format is as follows:
Please confirm you explicitly initiated this request from
Nonce:
- The abstract public key is a BCS serialized
SuiAbstractPublicKey. - The abstract signature is a BCS serialized
SuiAbstractSignature. - This module has been tested for the following wallets:
use 0x1::aptos_hash;use 0x1::auth_data;use 0x1::bcs;use 0x1::bcs_stream;use 0x1::common_account_abstractions_utils;use 0x1::ed25519;use 0x1::option;use 0x1::string;use 0x1::string_utils;use 0x1::transaction_context;use 0x1::vector;Enum SuiAbstractSignature
enum SuiAbstractSignature has dropVariants
MessageV1
Fields
-
signature: vector<u8> - The signature of the message in raw bytes
Constants
Invalid public key.
const EINVALID_PUBLIC_KEY: u64 = 6;Entry function payload is missing.
const EMISSING_ENTRY_FUNCTION_PAYLOAD: u64 = 1;Invalid signature.
const EINVALID_SIGNATURE: u64 = 5;Invalid signature type.
const EINVALID_SIGNATURE_TYPE: u64 = 2;Account address mismatch.
const EACCOUNT_ADDRESS_MISMATCH: u64 = 7;Invalid signature length.
const EINVALID_SIGNATURE_LENGTH: u64 = 4;Invalid signing scheme type.
const EINVALID_SIGNING_SCHEME_TYPE: u64 = 3;Structs
SuiAbstractPublicKey
Sui abstract public key defined with the
struct SuiAbstractPublicKey has dropIntentMessage
A wrapper struct that defines a message with its signing context (intent). https://github.com/MystenLabs/sui/blob/main/crates/shared-crypto/src/intent.rs#L168
struct IntentMessage has copy, drop, storeFields
-
intent: sui_derivable_account::Intent -
value: vector<u8>
Intent
Metadata specifying the scope, version, and application domain of the message. https://github.com/MystenLabs/sui/blob/main/crates/shared-crypto/src/intent.rs#L86
struct Intent has copy, drop, storeFields
Functions
get_signing_scheme
Returns the signing scheme for the given value.
fun get_signing_scheme(value: u8): sui_derivable_account::SuiSigningSchemeImplementation
fun get_signing_scheme(value: u8): SuiSigningScheme { if (value == 0) SuiSigningScheme::ED25519 else abort(EINVALID_SIGNING_SCHEME_TYPE)}deserialize_abstract_public_key
Deserializes the abstract public key which is supposed to be a bcs
serialized SuiAbstractPublicKey.
fun deserialize_abstract_public_key(abstract_public_key: &vector<u8>): sui_derivable_account::SuiAbstractPublicKeyImplementation
fun deserialize_abstract_public_key(abstract_public_key: &vector<u8>): SuiAbstractPublicKey { let stream = bcs_stream::new(*abstract_public_key); let sui_account_address = bcs_stream::deserialize_vector<u8>(&mut stream, |x| deserialize_u8(x)); let domain = bcs_stream::deserialize_vector<u8>(&mut stream, |x| deserialize_u8(x)); SuiAbstractPublicKey { sui_account_address, domain }}deserialize_abstract_signature
Returns a tuple of the signature.
fun deserialize_abstract_signature(abstract_signature: &vector<u8>): sui_derivable_account::SuiAbstractSignatureImplementation
fun deserialize_abstract_signature(abstract_signature: &vector<u8>): SuiAbstractSignature { let stream = bcs_stream::new(*abstract_signature); let signature_type = bcs_stream::deserialize_u8(&mut stream); if (signature_type == 0x00) { let signature = bcs_stream::deserialize_vector<u8>(&mut stream, |x| deserialize_u8(x)); SuiAbstractSignature::MessageV1 { signature } } else { abort(EINVALID_SIGNATURE_TYPE) }}split_signature_bytes
Splits raw signature bytes containing scheme flag (1 byte), signature (64 bytes) and public key (32 bytes)
to a tuple of (signing_scheme, signature, public_key)
public fun split_signature_bytes(bytes: &vector<u8>): (u8, vector<u8>, vector<u8>)Implementation
public fun split_signature_bytes(bytes: &vector<u8>): (u8, vector<u8>, vector<u8>) { // 1 + 64 + 32 = 97 bytes assert!(bytes.length() == 97, EINVALID_SIGNATURE_LENGTH);
let signing_scheme = bytes[0]; let abstract_signature_signature = vector::empty<u8>(); let abstract_signature_public_key = vector::empty<u8>();
// Extract signature (64 bytes) let i = 1; while (i < 65) { abstract_signature_signature.push_back(bytes[i]); i += 1; };
// Extract public key (32 bytes) while (i < 97) { abstract_signature_public_key.push_back(bytes[i]); i += 1; };
(signing_scheme, abstract_signature_signature, abstract_signature_public_key)}derive_account_address_from_public_key
Derives the account address from the public key and returns it is a hex string with “0x” prefix
fun derive_account_address_from_public_key(signing_scheme: u8, public_key_bytes: vector<u8>): vector<u8>Implementation
fun derive_account_address_from_public_key(signing_scheme: u8, public_key_bytes: vector<u8>): vector<u8> { // Create a vector with signing scheme and public key bytes let data_to_hash = vector[signing_scheme]; data_to_hash.append(public_key_bytes);
// Compute blake2b hash let sui_account_address = aptos_hash::blake2b_256(data_to_hash);
// Convert the address bytes to a hex string with "0x" prefix let sui_account_address_hex = b"0x"; let i = 0; while (i < sui_account_address.length()) { let byte = sui_account_address[i]; // Convert each byte to two hex characters let hex_chars = vector[ if ((byte >> 4) < 10) ((byte >> 4) + 0x30) else ((byte >> 4) - 10 + 0x61), if ((byte & 0xf) < 10) ((byte & 0xf) + 0x30) else ((byte & 0xf) - 10 + 0x61) ]; sui_account_address_hex.append(hex_chars); i += 1; };
// Return the account address as hex string sui_account_address_hex}authenticate_auth_data
public fun authenticate_auth_data(aa_auth_data: auth_data::AbstractionAuthData, entry_function_name: &vector<u8>)Implementation
public fun authenticate_auth_data( aa_auth_data: AbstractionAuthData, entry_function_name: &vector<u8>) { let abstract_signature = deserialize_abstract_signature(aa_auth_data.derivable_abstract_signature()); let (signing_scheme, abstract_signature_signature, abstract_signature_public_key) = split_signature_bytes(&abstract_signature.signature);
// Check siging scheme is Ed25519 as we currently only support this scheme assert!(get_signing_scheme(signing_scheme) == SuiSigningScheme::ED25519, EINVALID_SIGNING_SCHEME_TYPE);
// Derive the account address from the public key let sui_account_address = derive_account_address_from_public_key(signing_scheme, abstract_signature_public_key);
let derivable_abstract_public_key = aa_auth_data.derivable_abstract_public_key(); let abstract_public_key = deserialize_abstract_public_key(derivable_abstract_public_key);
// Check the account address matches the abstract public key assert!(&sui_account_address == &abstract_public_key.sui_account_address, EACCOUNT_ADDRESS_MISMATCH);
let public_key = new_validated_public_key_from_bytes(abstract_signature_public_key); assert!(public_key.is_some(), EINVALID_PUBLIC_KEY);
let digest_utf8 = string_utils::to_string(aa_auth_data.digest()).bytes(); // Build the raw message let raw_message = construct_message(&b"Sui", &sui_account_address, &abstract_public_key.domain, entry_function_name, digest_utf8);
// Prepend Intent to the message let intent = Intent { scope: PersonalMessage, version: V0, app_id: Sui, }; let msg = IntentMessage { intent, value: raw_message, }; // Serialize the whole struct let bcs_bytes = bcs::to_bytes<IntentMessage>(&msg);
// Hash full_message with blake2b256 let hash = aptos_hash::blake2b_256(bcs_bytes);
let signature = new_signature_from_bytes(abstract_signature_signature);
assert!( ed25519::signature_verify_strict( &signature, &public_key_into_unvalidated(public_key.destroy_some()), hash, ), EINVALID_SIGNATURE );}authenticate
Authorization function for domain account abstraction.
public fun authenticate(account: signer, aa_auth_data: auth_data::AbstractionAuthData): signerImplementation
public fun authenticate(account: signer, aa_auth_data: AbstractionAuthData): signer { daa_authenticate(account, aa_auth_data, |auth_data, entry_name| authenticate_auth_data(auth_data, entry_name))}Specification
derive_account_address_from_public_key
fun derive_account_address_from_public_key(signing_scheme: u8, public_key_bytes: vector<u8>): vector<u8>pragma verify = false;authenticate_auth_data
public fun authenticate_auth_data(aa_auth_data: auth_data::AbstractionAuthData, entry_function_name: &vector<u8>)pragma verify = false;authenticate
public fun authenticate(account: signer, aa_auth_data: auth_data::AbstractionAuthData): signerpragma verify = false;Enum SuiSigningScheme
Sui signing scheme as defined in https://github.com/MystenLabs/ts-sdks/blob/main/packages/typescript/src/cryptography/signature-scheme.ts#L19
enum SuiSigningScheme has dropVariants
ED25519
Fields
Enum IntentScope
https://github.com/MystenLabs/sui/blob/main/crates/shared-crypto/src/intent.rs#L60
enum IntentScope has copy, drop, storeVariants
TransactionData
Fields
TransactionEffects
Fields
CheckpointSummary
Fields
PersonalMessage
Fields
Enum IntentVersion
https://github.com/MystenLabs/sui/blob/main/crates/shared-crypto/src/intent.rs#L18
enum IntentVersion has copy, drop, storeVariants
V0
Fields
Enum AppId
https://github.com/MystenLabs/sui/blob/main/crates/shared-crypto/src/intent.rs#L35
enum AppId has copy, drop, store