Convert string to principal
Parse string addresses into principal types using c32 decoding in Clarity
(define-read-only (string-to-principal? (input (string-ascii 82)))(let (;; Find the dot separator for contract addresses(dot (default-to (len input) (index-of? input ".")));; Extract address part (skip first char which is version)(addr (unwrap! (slice? input u1 dot) ERR_INVALID_LENGTH));; Decode c32 characters to numbers(addressc32 (map unwrap-panic-uint (filter is-some-uint (map c32-index addr))));; Validate all characters are valid c32(isValidChars (asserts! (is-eq (len addr) (len addressc32)) ERR_INVALID_CHAR));; Extract version and decode address data(version (unwrap-panic (element-at? addressc32 u0)))(decoded (decode-address addressc32));; Verify checksum(checksum (verify-checksum decoded version)));; Construct principal with or without contract name(match (slice? input (+ u1 dot) (len input)) contract(principal-construct? (to-byte version) (get-address-bytes decoded) contract)(principal-construct? (to-byte version) (get-address-bytes decoded)))));; Example usage(string-to-principal? "SP2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKNRV9EJ7");; Returns (some SP2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKNRV9EJ7)(string-to-principal? "SP2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKNRV9EJ7.my-contract");; Returns (some SP2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKNRV9EJ7.my-contract)
Use cases
- Parsing user input addresses in contracts
- Converting stored string addresses to principals
- Validating address formats before use
- Building dynamic contract calls with string inputs
Key concepts
Stacks addresses use c32 encoding:
- c32 alphabet:
0123456789ABCDEFGHJKMNPQRSTVWXYZ
(no I, L, O, U) - Checksum: Last 4 bytes verify address integrity
- Version byte: First character indicates address type
- Contract addresses: Include
.contract-name
suffix