# 资产操作

资产模块提供了完整的资产管理功能，包括资产发行、转移、查询等操作。

## 资产查询

### 查询账户资产信息
```javascript
// 查询账户资产信息
const assetInfo = yield sdk.token.asset.getInfo({
  address: 'your-account-address',    // 账户地址
  code: 'CNY',                        // 资产代码
  issuer: 'issuer-address'            // 发行方地址
});

// 返回结果示例
{
  errorCode: 0,
  errorDesc: '',
  result: {
    assets: [
      {
        key: {
          code: 'CNY',
          issuer: 'issuer-address'
        },
        amount: '10000'
      }
    ]
  }
}
```

### 查询特定资产信息
```javascript
// 查询特定资产的详细信息
const specificAssetInfo = yield sdk.token.asset.getSpecificInfo({
  address: 'your-account-address',
  code: 'CNY',
  issuer: 'issuer-address'
});
```

## 资产发行

### 发行新资产
```javascript
// 发行资产操作
const issueOperation = {
  sourceAddress: address,     // 发行方地址
  code: 'CNY',               // 资产代码
  amount: '10000',           // 发行数量
  metadata: 'asset info'     // 可选，资产元数据
};

// 构建并提交发行资产交易
const response = yield sdk.operation.asset.issue(issueOperation);
```

### 发行资产的最佳实践
```javascript
// 发行资产前的检查
const checkBeforeIssue = async (code, amount) => {
  // 验证资产代码
  if (!/^[A-Z0-9]{1,64}$/.test(code)) {
    throw new Error('Invalid asset code');
  }
  
  // 验证发行数量
  if (Number(amount) <= 0 || Number(amount) > Number.MAX_SAFE_INTEGER) {
    throw new Error('Invalid amount');
  }
  
  // 检查是否已存在同名资产
  const existingAsset = await sdk.token.asset.getInfo({
    code: code,
    issuer: sourceAddress
  });
  
  if (existingAsset.result.assets.length > 0) {
    throw new Error('Asset already exists');
  }
};
```

## 资产转移

### 转移资产
```javascript
// 转移资产操作
const payAssetOperation = {
  sourceAddress: sourceAddress,    // 源账户地址
  destAddress: destAddress,        // 目标账户地址
  code: 'CNY',                     // 资产代码
  issuer: 'issuer-address',        // 资产发行方地址
  amount: '100',                   // 转移数量
  metadata: 'transfer info'        // 可选，转移说明
};

// 构建并提交转移资产交易
const response = yield sdk.operation.asset.pay(payAssetOperation);
```

### 批量转移资产
```javascript
// 批量转移资产
const batchTransferAsset = async (sourceAddress, transfers) => {
  // 构建批量转移操作
  const operations = transfers.map(transfer => ({
    type: 'payAsset',
    data: {
      sourceAddress: sourceAddress,
      destAddress: transfer.destAddress,
      code: transfer.code,
      issuer: transfer.issuer,
      amount: transfer.amount
    }
  }));

  // 构建交易
  const buildBlobResponse = await sdk.transaction.buildBlob({
    sourceAddress: sourceAddress,
    operations: operations,
    gasPrice: '1000',
    feeLimit: '1000000'
  });

  return buildBlobResponse;
};
```

## 资产管理

### 资产冻结/解冻
```javascript
// 冻结资产
const freezeAsset = async (assetCode, issuer) => {
  const operation = {
    sourceAddress: issuer,
    code: assetCode,
    metadata: 'freeze asset'
  };
  
  return await sdk.operation.asset.freeze(operation);
};

// 解冻资产
const unfreezeAsset = async (assetCode, issuer) => {
  const operation = {
    sourceAddress: issuer,
    code: assetCode,
    metadata: 'unfreeze asset'
  };
  
  return await sdk.operation.asset.unfreeze(operation);
};
```

### 资产增发
```javascript
// 增发资产
const additionalIssue = async (code, amount) => {
  const operation = {
    sourceAddress: issuerAddress,
    code: code,
    amount: amount,
    metadata: 'additional issue'
  };
  
  return await sdk.operation.asset.issue(operation);
};
```

## 最佳实践

1. 资产命名规范
```javascript
// 资产代码命名规则
const assetCodeRules = {
  pattern: /^[A-Z0-9]{1,64}$/,
  examples: {
    valid: ['CNY', 'USD', 'BTC', 'TOKEN1'],
    invalid: ['cny', 'US$', 'BTC-1', 'token#1']
  }
};

// 验证资产代码
function validateAssetCode(code) {
  if (!assetCodeRules.pattern.test(code)) {
    throw new Error('Invalid asset code format');
  }
}
```

2. 资产转移安全检查
```javascript
// 转移前的安全检查
async function transferSafetyCheck(operation) {
  // 检查地址有效性
  if (!sdk.account.isValid(operation.destAddress)) {
    throw new Error('Invalid destination address');
  }
  
  // 检查余额充足
  const balance = await sdk.token.asset.getBalance({
    address: operation.sourceAddress,
    code: operation.code,
    issuer: operation.issuer
  });
  
  if (Number(balance) < Number(operation.amount)) {
    throw new Error('Insufficient balance');
  }
  
  // 检查资产状态
  const assetInfo = await sdk.token.asset.getInfo({
    code: operation.code,
    issuer: operation.issuer
  });
  
  if (assetInfo.isFrozen) {
    throw new Error('Asset is frozen');
  }
}
```

3. 错误处理
```javascript
// 资产操作错误处理
async function handleAssetOperation(operation) {
  try {
    // 执行操作前的验证
    await validateOperation(operation);
    
    // 执行资产操作
    const response = await sdk.operation.asset.pay(operation);
    
    // 检查操作结果
    if (response.errorCode !== 0) {
      throw new Error(`Operation failed: ${response.errorDesc}`);
    }
    
    // 返回成功结果
    return {
      success: true,
      hash: response.result.hash
    };
  } catch (error) {
    // 处理错误
    console.error('Asset operation failed:', error);
    return {
      success: false,
      error: error.message
    };
  }
}
```

4. 资产监控
```javascript
// 监控资产变动
async function monitorAsset(address, assetCode, issuer) {
  let lastBalance = '0';
  
  setInterval(async () => {
    try {
      const currentBalance = await sdk.token.asset.getBalance({
        address,
        code: assetCode,
        issuer
      });
      
      if (currentBalance !== lastBalance) {
        console.log('Asset balance changed:', {
          previous: lastBalance,
          current: currentBalance,
          difference: String(Number(currentBalance) - Number(lastBalance))
        });
        lastBalance = currentBalance;
      }
    } catch (error) {
      console.error('Asset monitoring error:', error);
    }
  }, 5000); // 每5秒检查一次
}
```

5. 性能优化
```javascript
// 批量操作优化
async function optimizedBatchTransfer(transfers) {
  // 对相同接收方的转账进行合并
  const mergedTransfers = transfers.reduce((acc, transfer) => {
    const key = `${transfer.destAddress}-${transfer.code}-${transfer.issuer}`;
    if (!acc[key]) {
      acc[key] = { ...transfer };
    } else {
      acc[key].amount = String(Number(acc[key].amount) + Number(transfer.amount));
    }
    return acc;
  }, {});
  
  // 构建优化后的操作列表
  const operations = Object.values(mergedTransfers).map(transfer => ({
    type: 'payAsset',
    data: transfer
  }));
  
  return operations;
}
```