This proposal aims to provide a standardized method for on-chain treasury management of institutional assets, ensuring secure private key generation, hierarchical management, and departmental permission isolation while supporting asset security and transaction efficiency in multi-chain environments. By defining a unified derivation path and security mechanisms, this proposal offers an efficient and secure solution for treasury management.
Motivation
With the rapid development of blockchain and DeFi, secure management of on-chain assets has become critical. Traditional private key management struggles to meet the security demands of large organizations in complex scenarios, where hierarchical key management, permission controls, and multi-signature mechanisms are essential. This proposal provides a standardized solution for institutional treasury management, ensuring asset security and transaction efficiency.
Specification
Derivation Path
For secure on-chain treasury account key management, implementations MUST use the following hierarchical
deterministic (HD) path:
SHOULD use hardened derivation to isolate role-specific keys.
Compatibility Note:
Omitting the 44' layer MAY cause incompatibility with standard wallets (e.g., MetaMask).
Integrations with such wallets MUST implement custom plugins to handle this deviation.
Simplified Path for Smaller Entities
For entities without subsidiaries:
m/44'/60' / department_id' /0/ account_index
Compatibility Guarantee
This structure SHOULD ensure compatibility with mainstream BIP-44 wallets.
Key Derivation Algorithm
Implementations MUST adhere to:
E = Map<entity, List<Department>>
n = Layer2 curve order
path = m/44'/60'/entity_id' / department_id' / account_index
BIP32() = Official BIP-0032 derivation function on secp256k1
hash = SHA256
root_key = BIP32(path)
for each E:
key = hash(root_key|hierarchical_hash_to_index(entity,department))
return key
Cryptographic Requirements:
SHALL use BIP-0032 with secp256k1 for HD derivation.
MUST concatenate hashes with root keys to prevent cross-layer key leakage.
Compatibility Considerations
This specification is inspired by BIP-44 (m/purpose'/coin_type'/account'/change/address_index), but:
SHALL NOT use the change layer for Ethereum-based systems.
MAY extend the hierarchy beyond BIP-44’s 5-layer structure for organizational needs.
Rationale
The scenarios for which the proposal applies are:
Company and Department Isolation: Different subsidiaries within the group, as well as different departments within each subsidiary, can create isolated on-chain accounts. Enhanced derivation is used to isolate exposure risks.
Group Unified Management Authority: The group administrator holds the master private key, which can derive all subsidiary private keys, granting the highest authority to view and initiate transactions across the entire group, facilitating unified management by the group administrator.
Shared Department Private Key: If subsidiary A’s administrator, Alice, needs to share accounts under subsidiary A with a new administrator, Bob, she only needs to share the master private key of subsidiary A. Accounts from various departments can then be derived from this key.
Shared Audit Public Key: If the audit department needs to audit transactions under a specific department, the extended public key of the specified department can be shared with the audit department. Through this extended public key, all subordinate public keys under the department can be derived, allowing the audit department to track all transactions associated with these public key addresses.
Backwards Compatibility
This standard complies with BIP39、BIP32、BIP44.
Reference Implementation
"""
Secure Treasury Management System
Enterprise-grade hierarchical deterministic wallet implementation compliant with BIP-44
"""importhashlibimportloggingfromtypingimportTuple,Dictfrombip32utilsimportBIP32Keyfrometh_accountimportAccountfrommnemonicimportMnemonic# Add BIP39 support
# Configure logging
logging.basicConfig(level=logging.INFO)logger=logging.getLogger("TreasurySystem")classTreasurySystem:def__init__(self,mnemonic:str):"""
Initialize the treasury system
:param mnemonic: BIP-39 mnemonic (12/24 words)
"""ifnotMnemonic("english").check(mnemonic):raiseValueError("Invalid BIP-39 mnemonic")# Generate seed using standard BIP-39
self.seed=Mnemonic.to_seed(mnemonic,passphrase="")self.root_key=BIP32Key.fromEntropy(self.seed)logger.info("Treasury system initialized. Master key fingerprint: %s",self.root_key.Fingerprint().hex())@staticmethoddef_hierarchical_hash(entity:str,department:str)->Tuple[int,int]:"""
Hierarchical hash calculation (compliant with proposal spec)
Returns: (entity_index, department_index)
"""# Entity hash
entity_hash=hashlib.sha256(f"ENTITY:{entity}".encode()).digest()entity_index=int.from_bytes(entity_hash[:4],'big')|0x80000000# Department hash (chained)
dept_input=f"DEPT:{entity_hash.hex()}:{department}".encode()dept_hash=hashlib.sha256(dept_input).digest()dept_index=int.from_bytes(dept_hash[:4],'big')|0x80000000returnentity_index,dept_indexdef_derive_key(self,path:list)->BIP32Key:"""General key derivation method"""current_key=self.root_keyforindexinpath:ifnotisinstance(index,int):raiseTypeError(f"Invalid derivation index type: {type(index)}")current_key=current_key.ChildKey(index)returncurrent_keydefgenerate_account(self,entity:str,department:str,account_idx:int=0)->Dict[str,str]:"""
Generate department account (BIP44 5-layer structure)
Path: m/44'/60'/entity'/dept'/account_idx
"""e_idx,d_idx=self._hierarchical_hash(entity,department)# BIP-44 standard path
derivation_path=[0x8000002C,# 44' (hardened)
0x8000003C,# 60' (Ethereum)
e_idx,# entity_index (hardened)
d_idx,# department_index (hardened)
account_idx# address index
]key=self._derive_key(derivation_path)priv_key=key.PrivateKey().hex()return{'path':f"m/44'/60'/{e_idx}'/{d_idx}'/{account_idx}",'private_key':priv_key,# Warning: Never expose this in production
'address':Account.from_key(priv_key).address}defget_audit_xpub(self,entity:str,department:str)->str:"""
Retrieve department-level extended public key (for auditing)
Path: m/44'/60'/entity'/dept'
"""e_idx,d_idx=self._hierarchical_hash(entity,department)path=[0x8000002C,# 44'
0x8000003C,# 60'
e_idx,# entity'
d_idx# dept'
]returnself._derive_key(path).ExtendedKey()defget_dept_xprv(self,entity:str,department:str)->str:"""
Get department-level extended private key (strictly controlled)
Path: m/44'/60'/entity'/dept'
"""e_idx,d_idx=self._hierarchical_hash(entity,department)path=[0x8000002C,# 44'
0x8000003C,# 60'
e_idx,# entity'
d_idx# dept'
]returnself._derive_key(path).ExtendedKey()@staticmethoddefderive_addresses_from_xpub(xpub:str,count:int=20)->list:"""Derive addresses from extended public key (audit use)"""audit_key=BIP32Key.fromExtendedKey(xpub)return[Account.from_key(audit_key.ChildKey(i)# Address index
.PrivateKey()).addressforiinrange(count)]if__name__=="__main__":# Example usage (remove private key printing in production)
try:# Use standard mnemonic
mnemo=Mnemonic("english")mnemonic=mnemo.generate(strength=256)treasury=TreasurySystem(mnemonic)print(f"mnemonic: {mnemonic}")print("\n=== Finance Department Account Generation ===")finance_acc1=treasury.generate_account("GroupA","Finance",0)finance_acc2=treasury.generate_account("GroupA","Finance",1)print(f"Account1 path: {finance_acc1['path']}")print(f"Account1 address: {finance_acc1['address']}")print(f"Account1 private key: {finance_acc1['private_key']}")print(f"Account2 path: {finance_acc2['path']}")print(f"Account2 address: {finance_acc2['address']}")print(f"Account2 private key: {finance_acc2['private_key']}")print("\n=== Audit Verification Test===")audit_xpub=treasury.get_audit_xpub("GroupA","Finance")print(f"Audit xpub: {audit_xpub}")audit_addresses=TreasurySystem.derive_addresses_from_xpub(audit_xpub,2)print(f"Audit-derived addresses: {audit_addresses}")assertfinance_acc1['address']inaudit_addresses,"Audit verification failed"assertfinance_acc2['address']inaudit_addresses,"Audit verification failed"print("✅ Audit verification successful")print("\n=== Department Isolation Test ===")other_dept_acc=treasury.generate_account("GroupA","Audit",0)print(f"Account3 path: {other_dept_acc['path']}")print(f"Account3 address: {other_dept_acc['address']}")assertother_dept_acc['address']notinaudit_addresses,"Isolation breach"print("✅ Department isolation effective")print("\n=== Department Private Key Sharing Test ===")# Gets the department layer extension private key
dept_xprv=treasury.get_audit_xpub("GroupA","Finance").replace('xpub','xprv')# 实际应通过专用方法获取
print(f"Fiance xprv: {dept_xprv}")# Derive the account private key from the extension private key
dept_key=BIP32Key.fromExtendedKey(dept_xprv)derived_acc0_key=dept_key.ChildKey(0).PrivateKey().hex()derived_acc1_key=dept_key.ChildKey(1).PrivateKey().hex()print(f"Fiance derived_acc0_key: {derived_acc0_key}")print(f"Fiance derived_acc1_key: {derived_acc1_key}")# Verify the private key derivation capability
assertderived_acc0_key==finance_acc1['private_key'], \
"Account 0 private key derivation failed"assertderived_acc1_key==finance_acc2['private_key'], \
"Account 1 private key derivation failed"print("✅ Private key derivation from department xprv successful")exceptExceptionase:logger.error("System error: %s",e,exc_info=True)
run script:
pip install bip32utils eth_account
python stms.py
output:
Security Considerations
For treasury managers, hierarchical deterministic wallet management is more convenient, but it requires additional consideration of protective measures for the master key, such as schemes for splitting and storing mnemonic phrases or master keys.