以太坊开发问题及解决办法案例

在合约中向其它账户转入其他erc20代币

在需要使用其他erc20代币转账合约中定义token接口,并在接口中定义转账方法,然后根据以发布的ert20代币合约地址,将token接口转出对应的token进行转账。

例如:

pragma solidity ^0.4.16;

//token接口
interface token {
    function transfer(address receiver, uint amount) external ;
}

contract TransationContract {
    token public tokenReward;
    address owner;

constructor (address addressOfToken) public {
    owner = msg.sender;
    tokenReward = token(addressOfToken);
}

function transferToken(address receiver,uint256 amount) public {
   require(amount>0);
   tokenReward.transfer(receiver,amount);
}

}

如何给合约加入访问权限**

给比较敏感数据操作的方法添加函数修改器,在函数修改器中验证该操作者是否有对应的权限。

示例代码:

pragma solidity ^0.4.16;

contract TransationContract {
    address owner;
    mapping (address => bool) accessAllowed;
    event adminEvent(address addr,bool isAdd);

constructor (address addressOfToken) public {
    owner = msg.sender;

   accessAllowed[owner] = true;
}

function myMethod(address receiver,uint256 amount) onlyAdmin public {

   //业务逻辑...
   emit EventTransfer(receiver,amount);
}

//更换合约拥有者      
function changeOwner(address ownerAddr) public isOwner{
   owner =  ownerAddr;
}

//析构函数
function kill() isOwner public {
      selfdestruct(owner);
}

//设置管理员 
function setAdmin(address addr) isOwner public {
    require (msg.sender == owner);
    accessAllowed[addr] = true;
    emit adminEvent(addr,true);
}

//删除管理员 
function delAdmin(address addr) isOwner public {
    require (msg.sender == owner);
    accessAllowed[addr] = false;
    emit adminEvent(addr,false);
}

modifier isOwner() {
     if (msg.sender == owner) {
        _;
     }
}

modifier onlyAdmin(){
    require(accessAllowed[msg.sender] == true);
    _;
}

}
根据交易hash获取转账的ERC20代币的数量

根据交易hash,使用web3j获取交易收据,然后从交易收据日志中获取转账erc20数量。

CompletableFuture future = web3j
    .ethGetTransactionReceipt("0x464471df25a4bd37a2d88c62895cd64b23dc8d93ba700801fc4eea2eaaa3f164")
    .sendAsync();
  Future f = future.whenComplete((receipt, error) -> {
   if (error != null) {
    System.out.println(error);
    System.out.println("交易查询失败!" + error);
    return;
   }

   if (receipt.getResult() == null) {
    System.out.println("交易查询失败!" + error);
    return;
   }
   System.out.println(receipt.toString());
   String from = receipt.getResult().getFrom();
   String to = receipt.getResult().getTo();
   System.out.println("data:" + receipt.getResult().getLogs().get(0).getData());
   long tokenAmount = Integer.parseInt(receipt.getResult().getLogs().get(0).getData().substring(2,
     receipt.getResult().getLogs().get(0).getData().length()), 16);
   System.out.println("转账金额:" + tokenAmount);
   ta_traction.setText("from:" + from + "\n to:" + to + "\n WDNA数量:" + tokenAmount);
  });
web3j调用合约时动态设置gasLimit和gasPrice

在使用智能合约时,你可能需要根据调用函数指定不同的gasPrice和gasLimit。你可以通过为智能合约封装包创建自己的ContractGasProvider来实现这一点。

每一个生成的封装包都包含作为常量的所有智能合约方法名称,这有助于通过switch来进行编译时间匹配。
例如,使用Greeter合约:

Greeter greeter = new Greeter(...);
greeter.setGasProvider(new DefaultGasProvider() {
    @Override
    public BigInteger getGasPrice(String contractFunc) {
        switch (contractFunc) {
            case Greeter.FUNC_GREET: return BigInteger.valueOf(22_000_000_000L);
            case Greeter.FUNC_KILL: return BigInteger.valueOf(44_000_000_000L);
            default: throw new NotImplementedException();
        }
    }

    @Override
    public BigInteger getGasLimit(String contractFunc) {
        switch (contractFunc) {
            case Greeter.FUNC_GREET: return BigInteger.valueOf(4_300_000);
            case Greeter.FUNC_KILL: return BigInteger.valueOf(5_300_000);
            default: throw new NotImplementedException();
        }
    }
});
dapp开发中如何管理私钥

dapp接入钱包的可以使用钱包管理私钥,这种方式安全方便。

应用中没有钱包功能的又需要网络传输私钥的情况,要对私钥进行加密传输。

如何查询已经上交易所的代币和eth、btc等币之间的汇率

https://www.bcex.top/Api_Market/getPriceList

https://www.allcoin.ca/Api_Market/getPriceList

查询eth、btc等币当前交易价格
// 获取eth当前价格
  // 获取ETH价格
  String url = "http://www.btbase.org/currency/ethereum";
  // 访问链接并获取网络内容
  String result = sendRequet(url);
  // 使用正则表达式匹配
  String dataSrc = RegexString(result, "¥(.*?)");
  String finalSrc = dataSrc.replaceAll(",", "");
  // 转换格式,折算成人民币
  Float finalToFloat = Float.valueOf(finalSrc);
  Float retToFloat = Float.valueOf(WdnaToEthRate);
  float cny = finalToFloat * retToFloat;
  System.out.println("1WDNA 约等于 " + WdnaToEthRate + " ETH" + "," + " 约等于 " + cny + " CNY");

 static String RegexString(String targetStr, String patternStr) {
  // 定义一个样式模板,使用正则表达式
  Pattern pattern = Pattern.compile(patternStr);
  // 定义一个Match来匹配
  Matcher matcher = pattern.matcher(targetStr);
  // 如果找到了
  if (matcher.find()) {
   return matcher.group(1);
  }
  return "nothing";
 }
查询合约地址或账户地址中某种erc20余额**

参考地址:https://etherscan.io/apis#tokens

在使用erc20转账时要考虑代币的小数位数**

转账时包含了小数位数,转账前要算上小数位数,例如eth转账是wei,接受到的value要转换成对应的eth

#####solidity中的匿名方法问题

function () public payable{

//。。。

}

向合约中转入其他ERC20token时,匿名函数不会被调用,在转入ETH时匿名方法会被调用。

你可能感兴趣的:(以太坊开发问题及解决办法案例)