Account

Within the Bitmark Property System, an account represents any entity capable of creating and owning property, whether individuals, institutions, or organizations.

An account incorporates the public-private key-pair; the private key is needed to digitally sign any Bitmark blockchain record, including asset records, issue records, and transfer records.

Creating an account

You must create a new identity to participate on the Bitmark blockchain.

  • let account = new sdk.Account();
    
    // or
    const Account = sdk.Account;
    let account = new Account();
    
    
  • let account = try Account()
    
  • Account account = new Account();
    
  • acct, err := account.New()
    

Retrieving the account number

The account number of an account serves as a pseudonymous identifier within the Bitmark blockchain. It can represent:

  • The registrant of an asset
  • The owner of a bitmark
  • The sender of a bitmark transfer offer
  • The receiver of a bitmark transfer offer
  • let accountNumber = account.getAccountNumber();
    // ffzcoJeg7p6kJrV6VNhS6juuceTCKMmek1WrXopvbzNTvYqANy
    
  • let accountNumber = account.accountNumber()
    // ffzcoJeg7p6kJrV6VNhS6juuceTCKMmek1WrXopvbzNTvYqANy
    
  • String accountNumber = account.getAccountNumber();
    
  • acct, _ := account.New()
    accountNumber := acct.AccountNumber()
    

Exporting an account

There are two formats for exporting an account: seed and recovery phrase, both of which store all the required information to instantiate an account.

Both the seed and the recovery phrase can be used to derive the original private key of an account, so it is critical to store them securely.

Exporting a seed

The seed is the more compact format of an exported account. See Store seed to learn how to securely store seeds in mobile phones.

  • let seed = account.getSeed();
    // 9J87CAsHdFdoEu6N1unZk3sqhVBkVL8Z8
    
  • let seed = try account.toSeed()
    // 5XEECttvVsk5xPjZ1zrgtWoauw2xmPwTKCWEN5GF24UpaGZhAGS6tXd
    
  • Seed seed = account.getSeed();
    String encodedSeed = seed.getEncodedSeed();
    // 9J87CAsHdFdoEu6N1unZk3sqhVBkVL8Z8
    
  • acct, _ := account.New()
    seed := acct.Seed()
    

Exporting a recovery phrase

The recovery phrase, which consists of twelve mnemonic words, is superior to the seed for human interaction. If you don’t maintain custody of the seeds of your users, make sure you present the recovery phrase to them and teach them how to store it in a secure place.

Currently English and traditional Chinese phrases are supported.

  • // English version
    let recoveryPhrase = account.getRecoveryPhrase();
    // or
    let recoveryPhrase = account.getRecoveryPhrase("en");
    // "name gaze apart lamp lift zone believe steak session laptop crowd hill"
    
    // Chinese version
    let recoveryPhrase = account.getRecoveryPhrase("cn");
    // "箱 阻 起 归 彻 矮 问 栽 瓜 鼓 支 乐"
    
  • // English version
    let phrase = try account.getRecoverPhrase(language: .english)
    
    // Traditional Chinese version
    let phrase = try account.getRecoverPhrase(language: .chineseTraditional)
    
  • // English ver
    RecoveryPhrase recoveryPhrase = account.getRecoveryPhrase();
    // Or
    RecoveryPhrase recoveryPhrase = account.getRecoveryPhrase(Locale.ENGLISH);
    
    String[] mnemonicWords = recoveryPhrase.getMnemonicWords();
    // ["name", "gaze", "apart", "lamp", "lift", "zone",
    //  "believe", "steak", "session", "laptop", "crowd", "hill"]
    
    // Chinese ver
    RecoveryPhrase recoveryPhrase = account.getRecoveryPhrase(Locale.TRADITIONAL_CHINESE);
    String[] mnemonicWords = recoveryPhrase.getMnemonicWords();
    // ["箱", "阻", "起", "归", "彻", "矮", "问", "栽", "瓜", "鼓", "支", "乐"]
    
  • acct, _ := account.New()
    phrase, err := acct.RecoveryPhrase(language.AmericanEnglish)
    

Importing an account

As mentioned in Exporting an account, an account could be exported as either a seed or a recovery phrase, so there are two corresponding functions to recover an account from the supported exported formats.

Recovering from a seed

To instantiate an account from a given seed:

  • let account = Account.fromSeed("9J87CAsHdFdoEu6N1unZk3sqhVBkVL8Z8");
    
  • account = Account(fromSeed: "5XEECttvVsk5xPjZ1zrgtWoauw2xmPwTKCWEN5GF24UpaGZhAGS6tXd")
    
  • Account account = Account.fromSeed("9J87CAsHdFdoEu6N1unZk3sqhVBkVL8Z8");
    
  • acct, err := account.FromSeed("9J87CAsHdFdoEu6N1unZk3sqhVBkVL8Z8")
    

Recovering from a phrase

To instantiate an account from a given recovery phrase:

  • // English version
    let account = Account.fromRecoveryPhrase("name gaze apart lamp lift zone believe steak session laptop crowd hill");
    // or
    let account = Account.fromRecoveryPhrase("name gaze apart lamp lift zone believe steak session laptop crowd hill", "en");
    
    
    // Chinese version
    let account = Account.fromRecoveryPhrase("箱 阻 起 归 彻 矮 问 栽 瓜 鼓 支 乐", "cn");
    
  • // English version
    let account = try Account(recoverPhrase: [
        "music", "life", "stone", "brain", "slush", "mango",
         "diagram", "business", "dumb", "cinnamon", "coral", "year"],
        language: .english
    )
    
    // Traditional Chinese version
    let account = try Account(recoverPhrase: [
        "婆", "潮", "睛", "毫", "壤", "殿", "北", "謝", "人", "答", "隊", "星"],
        language: .chineseTraditional
    )
    
  • Account account = Account.fromRecoveryPhrase("name", "gaze", "apart", "lamp", "lift", "zone", "believe", "steak", "session", "laptop", "crowd", "hill"); // English
    
    // Or
    Account account = Account.fromRecoveryPhrase("箱", "阻", "起", "归", "彻", "矮", "问", "栽", "瓜", "鼓", "支", "乐"); // Chinese
    
    
  • acct, err := account.FromRecoveryPhrase(
        []string{
            "name", "gaze", "apart", "lamp", " lift", " zone",
            "believe", "steak", "session", "laptop", "crowd", "hill",
        },
        language.AmericanEnglish,
    )
    

Signing and verifying

An account can be used to sign an arbitrary message. Any party with the received message and the corresponding signature can then validate if the message was created by a known sender (authentication) and that the message was not altered in transit (integrity). This functionality is usually useful when you have a server application that needs to authenticate whether requests are from valid users.

  • let account = new Account();
    let message = "Hello, world!"; // message could be either string or buffer
    let signature = account.sign(message); // signature is a buffer
    
    let accountNumber = account.getAccountNumber();
    let isAuthentic = Account.verify(accountNumber, message, signature);
    
  • account := try Account()
    
    // create a signature
    let message = "Hello, world!".data(using: .utf8)!
    let signature = try account.sign(message: message)
    
    // verify the signature from other side
    let senderAccountNumber = account.address
    let isAuthentic = senderAccountNumber.verify(message: message, signature: signature)
    
  • final Account account = new Account();
    final accountNumber = account.getAccountNumber();
    final message = "Hello, world!".getBytes();
    
    // sign
    byte[] signature = account.sign(message);
    
    // verify
    boolean verified = Account.verify(accountNumber, signature, message);
    
    
  • // client side
    acct, _ := account.FromSeed("YOUR SEED")
    
    msg := []byte("Hello, world!")
    sig := acct.Sign(msg)
    
    // server side can verify if the message is from the client and
    err := account.Verify(acct.AccountNumber(), msg, sig)
    

Validating an account number

Validating a given account number verifies that it is valid in the current runtime environment (i.e., the format is correct and its network matches the network specified in the SDK config during initialization). The SDK functions return an error if the validation fails.

  • let isValid = Account.isValidAccountNumber(accountNumber);
    
  • let isValid = Account.isValidAccountNumber(accountNumber)
    
  • boolean isValid = Account.isValidAccountNumber(accountNumber);
    
  • err := account.ValidateAccountNumber("e1pFRPqPhY2gpgJTpCiwXDnVeouY9EjHY6STtKwdN6Z4bp4sog")