usdt (节点自动归集)

项目中用到usdt充值,由于走的是区块充值,节点服务器上是给每个用户都分配了一个usdt钱包地址,所以需要把可客户充值在每个钱包地址上的usdt归集到一块。

Omnicore提供了两个新的api omni_funded_sendomni_funded_sendall,这种方式的好处在于可以指定手续费的支付方,所有的令牌交易都可以使用统一的地址进行支付比特币手续费,而不需要发送者自身拥有比特币。但这里并未设定手续费的具体数量,系统将根据在配置文件中的关于手续费的配置文件进行动态设定。

omni_funded_send

调用参数

  • fromaddress:发送地址,字符串,必需
  • toaddress:接收地址,字符串,必需
  • propertyid:代币ID,数值,必需
  • amount:代币数量,字符串,必需
  • feeaddress:支付手续费的地址,字符串,必需
    /**
     * 方法:转账
     * @param $from
     * @param $to
     * @param $amount
     * @return array
     */
    function sendTransaction($from,$to,$amount)
    {
        try{
            $info = $this->usdt->omni_funded_send($from, $to ,1, $amount,'填写你需要支付手续费的比特币地址');
//            halt($info);
        }catch (BitcoindException $e){
            return ['msg' => '转出失败', 'status' => 201];
        }
        if ($info=='JSON value is not a string as expected'){
            return ['msg' => '请预留充足的BTC作为手续费', 'status' => 202];
        }
        if (strlen($info)<30 || $info=='Error choosing inputs for the send transaction'){
            return ['msg' => '转出异常,稍后重试', 'status' => 203];
        }
        return ['msg' => '转账信息发送成功,等待区块确认', 'status' => 200,'data'=>$info];
    }

然后利用定时任务将节点服务器中的各个账号中的usdt转账到同一账号中

<?php
/**
 * Created by PhpStorm.
 * User: 827169570@qq.com
 * Date: 2019/6/18
 * Time: 21:01
 */

namespace app\common\controller;


use app\admin\controller\usdts\Coins;
use app\v2\model\Ptsummary;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\Db;

class Summary extends Command
{
    protected function configure()
    {
        $this->setName('summary')
            ->setDescription('归集');
    }

    protected function execute(Input $input, Output $output){
        //每隔3小时触发一次
        $id = \swoole_timer_tick(60000, function ($timer_id) {
            file_put_contents('summary.log','开始'.PHP_EOL,FILE_APPEND);
//            $ptsummary=Db::name('ptsummary')->where(['status'=>1,'user_id'=>['in',[161,185]]])->order('id','asc')->select();
            $ptsummary=Db::name('ptsummary')->where(['status'=>1])->order('id','asc')->select();
            file_put_contents('summary.log',json_encode($ptsummary).PHP_EOL,FILE_APPEND);
            $recipient=getConfigValue('recipient');
            $commission=getConfigValue('commission');
            foreach ($ptsummary as $k=>$v){
                sleep(1);
                $usdt=(new Coins())->getCoins()->settxfee('0.0005');
                $usdt=(new Coins())->getCoins()->omni_funded_send($v['send'],$recipient,31,(string)$v['money'],$v['send']);
                file_put_contents('summary.log','tx_id--'.$usdt.'--'.$v['send'].PHP_EOL,FILE_APPEND);
                if(strpos($usdt,'wallet may be locked or fees may not be sufficient') !== false){
                    $usdt=(new Coins())->getCoins()->omni_funded_send($v['send'],$recipient,31,(string)$v['money'],$commission);
                    file_put_contents('summary.log','tx_id1--'.$usdt.'---'.$commission.PHP_EOL,FILE_APPEND);
                    if(strpos($usdt,'wallet may be locked or fees may not be sufficient') !== false){
                       continue;
                    }
                }
                if (strpos($usdt,'Error choosing inputs for the send transaction')!==false){
                    continue;
                }
                if (strpos($usdt,'Error committing transaction')!==false){
                    continue;
                }
                $update[]=[
                    'id'=>$v['id'],
                    'txid'=>$usdt,
                    'recipient'=>$recipient,
                    'status'=>2,
                    'update_time'=>date('YmdHis')
                ];
                file_put_contents('summary.log','tx_id1--'.json_encode($update).PHP_EOL,FILE_APPEND);
            }
            $lastptsummary=Db::name('ptsummary')->where(['status'=>2])->select();
            foreach ($lastptsummary as $kk=>$vv){
                sleep(1);
                $usdt_last=(new Coins())->gettransaction($vv['txid']);
                if (is_array($usdt_last)){
                    if ($usdt_last['ismine']){
                        if(isset($usdt_last['valid']) && $usdt_last['valid']==true && $usdt_last['confirmations']>=2){
                            $last_update[]=[
                                'id'=>$vv['id'],
                                'status'=>3,
                                'update_time'=>date('YmdHis')
                            ];
                        }

                    }
                }
            }
            $ptsummary= new Ptsummary();
            if (!empty($update)){
                file_put_contents('summary.log',json_encode($update).PHP_EOL,FILE_APPEND);
                $ptsummary->isUpdate(true)->saveAll($update);
            }
            if (!empty($last_update)){
                file_put_contents('summary.log',json_encode($last_update).PHP_EOL,FILE_APPEND);
                $ptsummary->isUpdate(true)->saveAll($last_update);
            }
            file_put_contents('summary.log','结束'.PHP_EOL,FILE_APPEND);

        });
    }
}
<?php
/**
 * Created by PhpStorm.
 * User: 827169570@qq.com
 * Date: 2019/5/25
 * Time: 0:11
 * WARNING: 未经本人许可, 禁止一切商用
 * CLASS: < 调usdt取方法 >
 */

namespace app\admin\controller\usdts;

class Coins
{
    protected $usdt;
    public function __construct()
    {
        $this->usdt=new Usdtcion('账号','密码','ip','端口');
    }
    /**
     * 方法:转账
     * @param $from
     * @param $to
     * @param $amount
     * @return array
     */
    function sendTransaction($from,$to,$amount)
    {
        try{
            $info = $this->usdt->omni_funded_send($from, $to ,31, $amount,'14PEfEATtjvG8ZPtjCnAp88HFETRbUXyvW');
        }catch (BitcoindException $e){
            return ['msg' => '转出失败', 'status' => 201];
        }
        if ($info=='JSON value is not a string as expected'){
            return ['msg' => '请预留充足的BTC作为手续费', 'status' => 202];
        }
        if (strlen($info)<30 || $info=='Error choosing inputs for the send transaction'){
            return ['msg' => '转出异常,稍后重试', 'status' => 203];
        }
        return ['msg' => '转账信息发送成功,等待区块确认', 'status' => 200,'data'=>$info];
    }

    function sendBtc($from,$to,$amount)
    {
        $connect=$this->usdt;
        $result = $connect->listunspent(3, 99999999, [$from]);
        if (empty($result)){
            $creater=[];
        }else{
            foreach ($result as $k=>$v){
                $txid = $v['txid'];
                $vout = $v['vout'];
                $creater[]=["txid" => $txid, "vout" => $vout];
            }
        }
        $raw_trans = $connect->createrawtransaction(
            $creater,
            ["$to" => $amount]
        );
        $fund_raw = $connect->fundrawtransaction(
            $raw_trans,
            [
                "changeAddress" => $from, //找零地址
                'feeRate' => 0.0004 //最高手续费
            ]
        );
        if ($fund_raw=='Insufficient funds'){
            return ['msg' => '请预留充足的BTC作为手续费', 'status' => 202];
        }
        $sign = $connect->signrawtransaction($fund_raw['hex']);
        $result = $connect->sendrawtransaction($sign['hex']);
        if (is_array($result) || strlen($result)<30){
            return ['msg' => '转出失败', 'status' => 201];
        }
        return ['msg' => '转账信息发送成功,等待区块确认', 'status' => 200,'data'=>$result];
    }

    /**
     * 方法:生成USDT地址 
     * @param $user_id
     * @return bool
     */
    public function usdtcoin($user_id)
    {
        $lists=$this->usdt->getaddressesbyaccount("$user_id");
        if (count($lists)>0){
            return $lists[0];
        }
        $address=$this->usdt->getnewaddress("$user_id");
        if (strlen($address) != 34) {
            return false;
        }
        return $address;
    }

    /**
     * 方法:获取余额
     * @param $address
     * @return int
     */
    function getBalance($address)
    {
        return $this->usdt->omni_getbalance($address,31)??0;
    }

    function getCoins()
    {
        return $this->usdt;
    }

}

归集BSC链上的USDT,您需要执行以下步骤: 1. 创建BSC钱包地址并获取私钥。 2. 使用Binance Smart Chain的RPC接口连接到BSC网络。 3. 使用USDT的合约地址和ABI,调用USDT合约的transfer方法将USDT从原地址转移到BSC钱包地址。 以下是Java代码示例: ```java import java.math.BigInteger; import java.util.Arrays; import org.web3j.abi.FunctionEncoder; import org.web3j.abi.FunctionReturnDecoder; import org.web3j.abi.TypeReference; import org.web3j.abi.datatypes.Function; import org.web3j.abi.datatypes.Type; import org.web3j.abi.datatypes.generated.Uint256; import org.web3j.crypto.Credentials; import org.web3j.protocol.Web3j; import org.web3j.protocol.core.DefaultBlockParameterName; import org.web3j.protocol.core.methods.request.Transaction; import org.web3j.protocol.core.methods.response.EthGetTransactionCount; import org.web3j.protocol.core.methods.response.EthSendTransaction; import org.web3j.protocol.http.HttpService; import org.web3j.tx.RawTransactionManager; import org.web3j.utils.Convert; import org.web3j.utils.Numeric; public class USDTTransfer { public static void main(String[] args) throws Exception { // BSC钱包地址和私钥 String fromAddress = "0x..."; String privateKey = "..."; Credentials credentials = Credentials.create(privateKey); // BSC节点地址 String bscRpcUrl = "https://bsc-dataseed.binance.org/"; Web3j web3j = Web3j.build(new HttpService(bscRpcUrl)); // USDT合约地址和ABI String usdtContractAddress = "0x..."; String usdtContractAbi = "[{\"constant\":true,\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_spender\",\"type\":\"address\"},{\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"name\":\"success\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"name\":\"\",\"type\":\"uint8\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_to\",\"type\":\"address\"},{\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"name\":\"success\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"name\":\"balance\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_from\",\"type\":\"address\"},{\"name\":\"_to\",\"type\":\"address\"},{\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"name\":\"success\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_owner\",\"type\":\"address\"},{\"name\":\"_spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"name\":\"remaining\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"initialSupply\",\"type\":\"uint256\"},{\"name\":\"tokenName\",\"type\":\"string\"},{\"name\":\"decimalUnits\",\"type\":\"uint8\"},{\"name\":\"tokenSymbol\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"_owner\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"_spender\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"}]"; // 获取USDT的decimals参数 Function decimalsFunction = new Function("decimals", Arrays.asList(), Arrays.asList(new TypeReference<Uint256>() {})); String encodedDecimals = FunctionEncoder.encode(decimalsFunction); org.web3j.protocol.core.methods.response.EthCall decimalsCall = web3j.ethCall(Transaction.createEthCallTransaction(fromAddress, usdtContractAddress, encodedDecimals), DefaultBlockParameterName.LATEST).send(); String decimalsHex = decimalsCall.getValue(); int decimals = Integer.parseInt(Numeric.cleanHexPrefix(decimalsHex), 16); // 转移USDT的数量 BigInteger amount = Convert.toWei("1", Convert.Unit.ETHER).multiply(BigInteger.TEN.pow(decimals)); // 获取BSC钱包地址的nonce EthGetTransactionCount ethGetTransactionCount = web3j.ethGetTransactionCount(fromAddress, DefaultBlockParameterName.LATEST).send(); BigInteger nonce = ethGetTransactionCount.getTransactionCount(); // 构造USDT转移交易数据 Function transferFunction = new Function("transfer", Arrays.asList(credentials.getAddress(), new Uint256(amount)), Arrays.asList(new TypeReference<Type>() {})); String encodedTransfer = FunctionEncoder.encode(transferFunction); // 使用USDT合约地址、nonce、gasPrice、gasLimit和交易数据构造交易 BigInteger gasPrice = Convert.toWei("5", Convert.Unit.GWEI).toBigInteger(); BigInteger gasLimit = BigInteger.valueOf(100000); Transaction transaction = Transaction.createFunctionCallTransaction(fromAddress, nonce, gasPrice, gasLimit, usdtContractAddress, encodedTransfer); // 签名交易并发送到BSC网络 RawTransactionManager rawTransactionManager = new RawTransactionManager(web3j, credentials); EthSendTransaction ethSendTransaction = rawTransactionManager.signAndSend(transaction); String transactionHash = ethSendTransaction.getTransactionHash(); System.out.println("USDT transfer transaction hash: " + transactionHash); } } ``` 请注意,您需要将代码中的钱包地址、私钥、USDT合约地址和ABI替换为您自己的值,并确保您的钱包具有足够的USDT余额以支付交易费用。此外,gasPrice和gasLimit参数应根据当前网络状况进行调整以确保交易能够成功被打包。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦夏夜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值