Ripple 账户标志设置
账户标志用于配置 Ripple 账户的各种行为和权限,通过 AccountSet
交易类型来设置。
🚀 快速开始
环境准备
npm install ripple-lib
基本设置
const RippleAPI = require('ripple-lib').RippleAPI;
// 创建 API 实例
const api = new RippleAPI({
server: 'wss://s.altnet.rippletest.net/', // 测试网
// server: 'wss://s1.ripple.com/', // 主网
});
📝 账户标志类型
1. 全局标志 (Global Flags)
const GLOBAL_FLAGS = {
// 禁用主密钥
DISABLE_MASTER: 0x00100000,
// 要求授权信任线
REQUIRE_AUTH: 0x00040000,
// 要求目的地标签
REQUIRE_DEST_TAG: 0x00020000,
// 禁用信任线
DISALLOW_XRP: 0x00080000,
// 允许信任线
ALLOW_XRP: 0x00080000,
};
2. 设置标志 (Set Flags)
const SET_FLAGS = {
// 设置要求授权信任线
REQUIRE_AUTH: 0x00040000,
// 设置要求目的地标签
REQUIRE_DEST_TAG: 0x00020000,
// 设置禁用信任线
DISALLOW_XRP: 0x00080000,
// 设置禁用主密钥
DISABLE_MASTER: 0x00100000,
// 设置默认信任线
DEFAULT_RIPPLE: 0x00800000,
// 设置不冻结
NO_FREEZE: 0x00200000,
// 设置全局冻结
GLOBAL_FREEZE: 0x00400000,
};
3. 清除标志 (Clear Flags)
const CLEAR_FLAGS = {
// 清除要求授权信任线
CLEAR_REQUIRE_AUTH: 0x00040000,
// 清除要求目的地标签
CLEAR_REQUIRE_DEST_TAG: 0x00020000,
// 清除禁用信任线
CLEAR_DISALLOW_XRP: 0x00080000,
// 清除禁用主密钥
CLEAR_DISABLE_MASTER: 0x00100000,
// 清除默认信任线
CLEAR_DEFAULT_RIPPLE: 0x00800000,
// 清除不冻结
CLEAR_NO_FREEZE: 0x00200000,
// 清除全局冻结
CLEAR_GLOBAL_FREEZE: 0x00400000,
};
🔄 账户标志设置流程
1. 连接网络
async function connectToNetwork() {
try {
await api.connect();
console.log('Connected to Ripple network');
} catch (error) {
console.error('Connection failed:', error);
}
}
2. 查询当前标志
async function getCurrentFlags(accountAddress) {
try {
const account = await api.getAccountInfo(accountAddress);
const flags = {
flags: account.Flags || 0,
flagsHex: '0x' + (account.Flags || 0).toString(16).toUpperCase(),
flagsSet: [],
flagsClear: [],
};
// 解析已设置的标志
if (account.Flags & SET_FLAGS.REQUIRE_AUTH) flags.flagsSet.push('REQUIRE_AUTH');
if (account.Flags & SET_FLAGS.REQUIRE_DEST_TAG) flags.flagsSet.push('REQUIRE_DEST_TAG');
if (account.Flags & SET_FLAGS.DISALLOW_XRP) flags.flagsSet.push('DISALLOW_XRP');
if (account.Flags & SET_FLAGS.DISABLE_MASTER) flags.flagsSet.push('DISABLE_MASTER');
if (account.Flags & SET_FLAGS.DEFAULT_RIPPLE) flags.flagsSet.push('DEFAULT_RIPPLE');
if (account.Flags & SET_FLAGS.NO_FREEZE) flags.flagsSet.push('NO_FREEZE');
if (account.Flags & SET_FLAGS.GLOBAL_FREEZE) flags.flagsSet.push('GLOBAL_FREEZE');
console.log('Current account flags:', flags);
return flags;
} catch (error) {
console.error('Failed to get current flags:', error);
}
}
3. 准备设置标志交易
async function prepareSetFlags(accountAddress, flags, clearFlags = 0) {
try {
const preparedTx = await api.prepareTransaction(
{
TransactionType: 'AccountSet',
Account: accountAddress,
Flags: flags,
ClearFlag: clearFlags,
},
{
maxLedgerVersionOffset: 75,
}
);
console.log('Set flags transaction prepared:', preparedTx);
return preparedTx;
} catch (error) {
console.error('Failed to prepare set flags transaction:', error);
}
}
4. 签名和提交
async function signAndSubmitFlags(preparedTx, secret) {
try {
// 签名交易
const signed = api.sign(preparedTx.txJSON, secret);
console.log('Flags transaction signed');
console.log('Transaction ID:', signed.id);
// 提交交易
const result = await api.submit(signed.signedTransaction);
console.log('Flags transaction submitted');
console.log('Result code:', result.resultCode);
console.log('Result message:', result.resultMessage);
return result;
} catch (error) {
console.error('Failed to sign and submit flags transaction:', error);
}
}
🔄 完整标志设置示例
基本标志设置
const account_address = 'rfXgErjK96k59evDnC22zX7vRo2hYaSiqc';
const secret = 'ssHAaRfvdDsF62da3dpDHgxHSnw4d';
async function setAccountFlags() {
try {
// 1. 连接网络
await api.connect();
// 2. 查询当前标志
const currentFlags = await getCurrentFlags(account_address);
console.log('Current flags:', currentFlags);
// 3. 设置新标志
const newFlags = SET_FLAGS.REQUIRE_AUTH | SET_FLAGS.REQUIRE_DEST_TAG;
const preparedTx = await prepareSetFlags(account_address, newFlags);
// 4. 签名和提交
const result = await signAndSubmitFlags(preparedTx, secret);
// 5. 验证设置结果
if (result.resultCode === 'tesSUCCESS') {
console.log('Flags successfully set!');
// 等待几个账本确认
await new Promise(resolve => setTimeout(resolve, 5000));
// 验证新标志
const updatedFlags = await getCurrentFlags(account_address);
console.log('Updated flags:', updatedFlags);
}
// 6. 断开连接
await api.disconnect();
return result;
} catch (error) {
console.error('Set flags failed:', error);
await api.disconnect();
}
}
⚙️ 高级标志管理
标志管理器类
class AccountFlagsManager {
constructor(accountAddress, api) {
this.accountAddress = accountAddress;
this.api = api;
this.currentFlags = 0;
this.flagHistory = [];
}
// 获取当前标志
async refreshFlags() {
try {
const account = await this.api.getAccountInfo(this.accountAddress);
this.currentFlags = account.Flags || 0;
return this.currentFlags;
} catch (error) {
console.error('Failed to refresh flags:', error);
throw error;
}
}
// 检查标志是否设置
hasFlag(flag) {
return (this.currentFlags & flag) !== 0;
}
// 设置标志
async setFlag(flag) {
try {
const newFlags = this.currentFlags | flag;
const result = await this.setFlags(newFlags);
if (result.resultCode === 'tesSUCCESS') {
this.currentFlags = newFlags;
this.flagHistory.push({
action: 'set',
flag: flag,
timestamp: new Date(),
result: result,
});
}
return result;
} catch (error) {
console.error('Failed to set flag:', error);
throw error;
}
}
// 清除标志
async clearFlag(flag) {
try {
const newFlags = this.currentFlags & ~flag;
const result = await this.setFlags(newFlags);
if (result.resultCode === 'tesSUCCESS') {
this.currentFlags = newFlags;
this.flagHistory.push({
action: 'clear',
flag: flag,
timestamp: new Date(),
result: result,
});
}
return result;
} catch (error) {
console.error('Failed to clear flag:', error);
throw error;
}
}
// 设置多个标志
async setFlags(flags) {
try {
const preparedTx = await this.api.prepareTransaction(
{
TransactionType: 'AccountSet',
Account: this.accountAddress,
Flags: flags,
},
{
maxLedgerVersionOffset: 75,
}
);
const signed = this.api.sign(preparedTx.txJSON, this.secret);
const result = await this.api.submit(signed.signedTransaction);
return result;
} catch (error) {
console.error('Failed to set flags:', error);
throw error;
}
}
// 获取标志历史
getFlagHistory() {
return this.flagHistory;
}
// 导出标志配置
exportFlagConfiguration() {
return {
accountAddress: this.accountAddress,
currentFlags: this.currentFlags,
currentFlagsHex: '0x' + this.currentFlags.toString(16).toUpperCase(),
flagHistory: this.flagHistory,
timestamp: new Date().toISOString(),
};
}
}
预设标志配置
function getPresetFlagConfigurations() {
return {
// 安全配置
'secure': {
name: 'Secure Account',
description: '高安全性配置,要求授权和目的地标签',
flags: SET_FLAGS.REQUIRE_AUTH | SET_FLAGS.REQUIRE_DEST_TAG | SET_FLAGS.DISABLE_MASTER,
clearFlags: 0,
},
// 企业配置
'enterprise': {
name: 'Enterprise Account',
description: '企业级配置,支持信任线和冻结功能',
flags: SET_FLAGS.REQUIRE_AUTH | SET_FLAGS.DEFAULT_RIPPLE | SET_FLAGS.NO_FREEZE,
clearFlags: 0,
},
// 交易配置
'trading': {
name: 'Trading Account',
description: '交易账户配置,支持各种代币',
flags: SET_FLAGS.DEFAULT_RIPPLE,
clearFlags: 0,
},
// 冷存储配置
'cold-storage': {
name: 'Cold Storage',
description: '冷存储配置,禁用主密钥',
flags: SET_FLAGS.DISABLE_MASTER | SET_FLAGS.NO_FREEZE,
clearFlags: 0,
},
// 默认配置
'default': {
name: 'Default Account',
description: '默认配置,无特殊限制',
flags: 0,
clearFlags: 0,
},
};
}
🔍 标志状态查询
批量标志查询
async function batchQueryFlags(accountAddresses) {
try {
const results = [];
for (const address of accountAddresses) {
try {
const flags = await getCurrentFlags(address);
results.push({
address: address,
flags: flags,
success: true,
});
} catch (error) {
results.push({
address: address,
error: error.message,
success: false,
});
}
}
console.log('Batch flags query completed:', results);
return results;
} catch (error) {
console.error('Batch query failed:', error);
}
}
标志变化监控
class FlagChangeMonitor {
constructor(accountAddress, api) {
this.accountAddress = accountAddress;
this.api = api;
this.previousFlags = 0;
this.monitoring = false;
this.changeCallbacks = [];
}
// 开始监控
async startMonitoring(interval = 10000) {
if (this.monitoring) {
console.log('Already monitoring');
return;
}
try {
// 获取初始标志
const account = await this.api.getAccountInfo(this.accountAddress);
this.previousFlags = account.Flags || 0;
this.monitoring = true;
this.monitorInterval = setInterval(async () => {
await this.checkForChanges();
}, interval);
console.log('Flag monitoring started');
} catch (error) {
console.error('Failed to start monitoring:', error);
}
}
// 停止监控
stopMonitoring() {
if (this.monitorInterval) {
clearInterval(this.monitorInterval);
this.monitoring = false;
console.log('Flag monitoring stopped');
}
}
// 检查变化
async checkForChanges() {
try {
const account = await this.api.getAccountInfo(this.accountAddress);
const currentFlags = account.Flags || 0;
if (currentFlags !== this.previousFlags) {
const changes = this.analyzeFlagChanges(this.previousFlags, currentFlags);
console.log('Flag changes detected:', changes);
// 触发回调
this.changeCallbacks.forEach(callback => {
callback(changes);
});
this.previousFlags = currentFlags;
}
} catch (error) {
console.error('Failed to check for changes:', error);
}
}
// 分析标志变化
analyzeFlagChanges(oldFlags, newFlags) {
const added = newFlags & ~oldFlags;
const removed = oldFlags & ~newFlags;
return {
oldFlags: oldFlags,
newFlags: newFlags,
added: added,
removed: removed,
addedHex: '0x' + added.toString(16).toUpperCase(),
removedHex: '0x' + removed.toString(16).toUpperCase(),
timestamp: new Date().toISOString(),
};
}
// 添加变化回调
onFlagChange(callback) {
this.changeCallbacks.push(callback);
}
// 移除变化回调
removeCallback(callback) {
const index = this.changeCallbacks.indexOf(callback);
if (index > -1) {
this.changeCallbacks.splice(index, 1);
}
}
}
🚨 错误处理
标志特定错误
function handleFlagError(error) {
if (error.data && error.data.error_code) {
switch (error.data.error_code) {
case 'temINVALID_FLAG':
console.error('Invalid flag value specified');
break;
case 'temMALFORMED':
console.error('Malformed flag transaction');
break;
case 'tecNO_PERMISSION':
console.error('No permission to modify flags');
break;
case 'tecINSUFFICIENT_FEE':
console.error('Insufficient fee for flag transaction');
break;
default:
console.error('Unknown flag error:', error.data.error_code);
}
} else {
console.error('Network error:', error.message);
}
}
标志验证
function validateFlagConfiguration(flags, clearFlags = 0) {
const validation = {
valid: true,
errors: [],
warnings: [],
recommendations: [],
};
// 检查标志值
if (flags < 0 || flags > 0xFFFFFFFF) {
validation.errors.push('Invalid flags value');
validation.valid = false;
}
// 检查清除标志值
if (clearFlags < 0 || clearFlags > 0xFFFFFFFF) {
validation.errors.push('Invalid clear flags value');
validation.valid = false;
}
// 检查冲突标志
const conflictingFlags = [
{ flag: SET_FLAGS.REQUIRE_AUTH, opposite: SET_FLAGS.CLEAR_REQUIRE_AUTH },
{ flag: SET_FLAGS.REQUIRE_DEST_TAG, opposite: SET_FLAGS.CLEAR_REQUIRE_DEST_TAG },
{ flag: SET_FLAGS.DISALLOW_XRP, opposite: SET_FLAGS.CLEAR_DISALLOW_XRP },
];
for (const conflict of conflictingFlags) {
if ((flags & conflict.flag) && (clearFlags & conflict.opposite)) {
validation.warnings.push(`Conflicting flags: setting and clearing ${conflict.flag}`);
}
}
// 生成建议
if (validation.warnings.length > 0) {
validation.recommendations.push('Review conflicting flag settings');
}
if (validation.errors.length > 0) {
validation.recommendations.push('Fix all errors before proceeding');
}
return validation;
}
📊 标志分析工具
标志分析器
class FlagAnalyzer {
constructor(flags) {
this.flags = flags;
}
// 获取所有设置的标志
getSetFlags() {
const setFlags = [];
if (this.flags & SET_FLAGS.REQUIRE_AUTH) setFlags.push('REQUIRE_AUTH');
if (this.flags & SET_FLAGS.REQUIRE_DEST_TAG) setFlags.push('REQUIRE_DEST_TAG');
if (this.flags & SET_FLAGS.DISALLOW_XRP) setFlags.push('DISALLOW_XRP');
if (this.flags & SET_FLAGS.DISABLE_MASTER) setFlags.push('DISABLE_MASTER');
if (this.flags & SET_FLAGS.DEFAULT_RIPPLE) setFlags.push('DEFAULT_RIPPLE');
if (this.flags & SET_FLAGS.NO_FREEZE) setFlags.push('NO_FREEZE');
if (this.flags & SET_FLAGS.GLOBAL_FREEZE) setFlags.push('GLOBAL_FREEZE');
return setFlags;
}
// 计算安全分数
calculateSecurityScore() {
let score = 0;
const setFlags = this.getSetFlags();
// 基于设置的标志计算分数
if (setFlags.includes('REQUIRE_AUTH')) score += 25;
if (setFlags.includes('REQUIRE_DEST_TAG')) score += 15;
if (setFlags.includes('DISABLE_MASTER')) score += 20;
if (setFlags.includes('NO_FREEZE')) score += 10;
if (setFlags.includes('GLOBAL_FREEZE')) score += 15;
return Math.min(100, score);
}
// 生成标志报告
generateReport() {
const setFlags = this.getSetFlags();
const securityScore = this.calculateSecurityScore();
return {
flags: this.flags,
flagsHex: '0x' + this.flags.toString(16).toUpperCase(),
setFlags: setFlags,
securityScore: securityScore,
securityLevel: this.getSecurityLevel(securityScore),
recommendations: this.generateRecommendations(setFlags, securityScore),
timestamp: new Date().toISOString(),
};
}
// 获取安全级别
getSecurityLevel(score) {
if (score >= 80) return 'HIGH';
if (score >= 60) return 'MEDIUM';
if (score >= 40) return 'LOW';
return 'VERY_LOW';
}
// 生成建议
generateRecommendations(setFlags, securityScore) {
const recommendations = [];
if (!setFlags.includes('REQUIRE_AUTH')) {
recommendations.push('Consider enabling REQUIRE_AUTH for better security');
}
if (!setFlags.includes('REQUIRE_DEST_TAG')) {
recommendations.push('Consider enabling REQUIRE_DEST_TAG to prevent accidental payments');
}
if (!setFlags.includes('DISABLE_MASTER')) {
recommendations.push('Consider disabling master key for cold storage');
}
if (securityScore < 60) {
recommendations.push('Security score is low, consider enabling more security flags');
}
return recommendations;
}
}
🔐 安全最佳实践
标志安全配置
function configureSecureFlags() {
return {
// 1. 基本安全标志
basic: {
REQUIRE_AUTH: true,
REQUIRE_DEST_TAG: true,
DISABLE_MASTER: false, // 根据需要设置
},
// 2. 高级安全标志
advanced: {
NO_FREEZE: true,
GLOBAL_FREEZE: false, // 谨慎使用
DEFAULT_RIPPLE: true,
},
// 3. 企业安全标志
enterprise: {
REQUIRE_AUTH: true,
REQUIRE_DEST_TAG: true,
DISABLE_MASTER: true,
NO_FREEZE: true,
DEFAULT_RIPPLE: true,
},
// 4. 冷存储安全标志
coldStorage: {
DISABLE_MASTER: true,
NO_FREEZE: true,
REQUIRE_AUTH: true,
},
};
}
标志变更审计
class FlagChangeAuditor {
constructor() {
this.auditLog = [];
}
// 记录标志变更
logFlagChange(accountAddress, oldFlags, newFlags, reason, operator) {
const auditEntry = {
timestamp: new Date().toISOString(),
accountAddress: accountAddress,
oldFlags: oldFlags,
newFlags: newFlags,
oldFlagsHex: '0x' + oldFlags.toString(16).toUpperCase(),
newFlagsHex: '0x' + newFlags.toString(16).toUpperCase(),
reason: reason,
operator: operator,
changes: this.analyzeChanges(oldFlags, newFlags),
};
this.auditLog.push(auditEntry);
console.log('Flag change audited:', auditEntry);
return auditEntry;
}
// 分析变更
analyzeChanges(oldFlags, newFlags) {
const added = newFlags & ~oldFlags;
const removed = oldFlags & ~newFlags;
return {
added: added,
removed: removed,
addedHex: '0x' + added.toString(16).toUpperCase(),
removedHex: '0x' + removed.toString(16).toUpperCase(),
};
}
// 获取审计日志
getAuditLog(accountAddress = null) {
if (accountAddress) {
return this.auditLog.filter(entry => entry.accountAddress === accountAddress);
}
return this.auditLog;
}
// 导出审计日志
exportAuditLog() {
return JSON.stringify(this.auditLog, null, 2);
}
// 清理旧日志
cleanupOldLogs(maxAge = 30 * 24 * 60 * 60 * 1000) { // 30天
const cutoff = Date.now() - maxAge;
this.auditLog = this.auditLog.filter(entry =>
new Date(entry.timestamp).getTime() > cutoff
);
}
}
📱 移动端支持
移动端标志管理
class MobileFlagManager {
constructor() {
this.api = null;
this.offlineMode = false;
}
// 配置移动端 API
configureMobileAPI() {
return {
timeout: 15000,
retries: 2,
compression: true,
mobileOptimized: true,
};
}
// 离线标志配置
async prepareOfflineFlags(accountAddress, flags) {
try {
const offlineConfig = {
accountAddress,
flags,
flagsHex: '0x' + flags.toString(16).toUpperCase(),
timestamp: new Date().toISOString(),
offline: true,
};
console.log('Offline flags configuration prepared:', offlineConfig);
return offlineConfig;
} catch (error) {
console.error('Offline flags preparation failed:', error);
}
}
// 在线标志设置
async setFlagsOnline(accountAddress, flags, secret) {
try {
await this.api.connect();
const result = await this.setFlagsWithConfig(accountAddress, flags, secret);
await this.api.disconnect();
return result;
} catch (error) {
console.error('Online flags setting failed:', error);
await this.api.disconnect();
throw error;
}
}
}
📚 最佳实践
- 谨慎设置: 仔细考虑每个标志的影响
- 测试验证: 在测试网上测试标志配置
- 文档记录: 记录所有标志变更的原因和影响
- 定期审查: 定期审查标志配置的合理性
- 备份配置: 备份重要的标志配置信息
- 权限控制: 限制标志修改的权限