主頁 > 區塊鏈 > Java FilCoin的充值以及上鏈操作詳情流程(附有代碼)

Java FilCoin的充值以及上鏈操作詳情流程(附有代碼)

2021-09-27 10:07:35 區塊鏈

對于fil的充提,公司原來用的是www.ztpay.org這個網站提供的服務,這個平臺后面卷款跑路了,導致公司損失了十幾萬,沒辦法,后面想去找一些比較可靠的第三方平臺,但是由于每個月的服務費都要幾萬塊,所以公司就要求能不能自己部署節點,然后自己提供充提服務,但是部署節點有個問題是,由于服務器的性能不是很好,磁盤容量不夠,導致需要經常清資料,這樣的運維成本比較大,后面發現可以直接使用infura提供的服務,Ethereum API | IPFS API & Gateway | ETH Nodes as a Service | Infura

但是infura有個缺點就是,它不提供完整的區塊鏈資訊,只是提供三天內產生的區塊資訊,這個要特別注意一下,不過這個對于大多數的應用來說,都不是什么問題,

一、在infura上注冊一個應用

1、注冊并登陸infura平臺,進入到以下控制臺

2、點擊左邊的選單欄"FILCOIN",進入filcoin的設定頁面

3、點擊右上角的"CREATE NEW PROJECT"按鈕,在彈出的彈框中輸入專案的名稱

4、如下圖所示,我們就在infura創建了一個filCoin的專案,記住“PROJECT ID” 和"PROJECT SECRET",這兩個值在后面的操作中,我們要用到,

二、關鍵代碼

1、fil節點地址配置類

public class FilApiConfig {
    //指定fil節點的地址
    public final static String FIL_RPC_URL = "https://filecoin.infura.io";
    

    public final static String FIL_METHOD_CHAINGETTIPSETBYHEIGHT =   "Filecoin.ChainGetTipSetByHeight";
    public final static String FIL_METHOD_CHAINGETBLOCKMESSAGES = "Filecoin.ChainGetBlockMessages";
    public final static String FIL_METHOD_CHAINHEAD = "Filecoin.ChainHead";
}

2、fil的http請求工具類(主要配置權限認證)

import com.alibaba.fastjson.JSONObject;
import com.alpha.fil.mining.pool.common.util.filChain.config.FilApiConfig;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import okhttp3.Credentials;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

public class FilHttpUtils {


    private static RestTemplate restTemplate;
    private static ObjectMapper objectMapper = new ObjectMapper();
    private static HttpHeaders headers = new HttpHeaders();
    private static JSONObject jsonObject = new JSONObject();

    static {
        SimpleClientHttpRequestFactory clientHttpRequestFactory = new SimpleClientHttpRequestFactory();
        clientHttpRequestFactory.setConnectTimeout(20 * 1000);
        clientHttpRequestFactory.setReadTimeout(20 * 1000);
        restTemplate = new RestTemplate(clientHttpRequestFactory);
        objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

        headers.add("Content-Type", "application/json");
        //Infura提供的訪問點需要http basic身份認證
       String credential = Credentials.basic("專案ID", "秘鑰");

        //如果是自己部署的fil節點,則在節點配置上拿到請求秘鑰,配置如下
         //String credential = "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJBbGxvdyI6WyJyZWFkIiwid3JpdGUiLCJzaWduIiwiYWRtaW4iXX0.eqQKY2EE9dgQ3f6PgEM7B-IEPLMYWJpkOZkUf-BemhE";


        headers.add("Authorization", credential);

        jsonObject.put("jsonrpc", "2.0");
        jsonObject.put("id", 1);
    }

    public static Optional<String> post(List<Object> object, String method) {
        jsonObject.put("method", method);
        jsonObject.put("params", object);
        HttpEntity<String> httpEntity = new HttpEntity<>(jsonObject.toString(), headers);
        ResponseEntity<String> mapResponseEntity = restTemplate.postForEntity(FilApiConfig.FIL_RPC_URL, httpEntity, String.class);
        return Optional.ofNullable(mapResponseEntity).filter(x -> x.getStatusCode() == HttpStatus.OK).map(x -> x.getBody());
    }

    public static Optional<String> get(String url) {
        try {
            ResponseEntity<String> mapResponseEntity = restTemplate.getForEntity(url, String.class);
            return Optional.ofNullable(mapResponseEntity).filter(x -> x.getStatusCode() == HttpStatus.OK).map(x -> x.getBody());
        } catch (RestClientException e) {
            e.printStackTrace();
        }
        return Optional.empty();
    }

  
}

3、fil的操作類(包含充提操作,測驗例子都在main函式中)

package com.canye.fil.demo.filChain;

import cn.hutool.core.codec.Base32;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.HexUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.canye.fil.demo.filChain.blake.Blake2b;
import com.canye.fil.demo.filChain.config.FilecoinCnt;
import com.canye.fil.demo.filChain.crypto.ECKey;
import com.canye.fil.demo.filChain.handler.TransactionHandler;
import com.canye.fil.demo.filChain.vo.*;
import org.apache.commons.lang3.StringUtils;


import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * fil的工具類
 * @author plb
 * @date 2021-06-04 14:50
 */
public class FilCoinUtil {
    /**
     * 獲取余額
     * @param address  地址
     * @return
     */
    public static BigDecimal  getBalance(String address){
        try{
            String method = "Filecoin.WalletBalance";
            List<Object> object = new ArrayList<>();
            object.add(address);
            Optional optional = FilHttpUtils.post(object,method);
            JSONObject dataJson = JSONObject.parseObject(String.valueOf(optional.get()));
            System.out.println("FilCoinUtil.getBalance " + address + " | res:" + dataJson);
            BigDecimal amount = dataJson.getBigDecimal("result");
            amount = amount.divide(BigDecimal.TEN.pow(18));
            return amount;
        }catch (Exception e){
            System.out.println("FilCoinUtil.getBalance: " + address + e.getMessage());
            throw  new RuntimeException("獲取余額失敗",e);
        }
    }

    /**
     * 檢測地址是否有效
     * @param address    地址
     * @return
     */
    public static boolean checkAddress(String address){
        try{
            String method = "Filecoin.WalletValidateAddress";
            List<Object> object = new ArrayList<>();
            object.add(address);
            Optional optional = FilHttpUtils.post(object,method);
            JSONObject dataJson = JSONObject.parseObject(String.valueOf(optional.get()));
            System.out.println("FilCoinUtil.checkAddress " + address + "|res:" + dataJson);
            if(dataJson.containsKey("result") && dataJson.getString("result").equals(address)) {
                return true;
            }
            return false;
        }catch (Exception e){
            System.out.println("FilCoinUtil.checkAddress: " + address+ e.getMessage());
            throw  new RuntimeException("檢驗地址失敗",e);
        }
    }

    /**
     * 生成地址
     * @return
     */
    public static WalletResult createWallet() {
        try {
            ECKey ecKey = new ECKey();
            byte[] privKeyBytes = ecKey.getPrivKeyBytes();
            byte[] pubKey = ecKey.getPubKey();
            if (privKeyBytes == null || privKeyBytes.length < 1) {
                throw new RuntimeException("create wallet error");
            }
            String filAddress = byteToAddress(pubKey);
            String privatekey = HexUtil.encodeHexStr(privKeyBytes);
            return WalletResult.builder().address(filAddress).privatekey(privatekey).build();
        }catch (Exception e){
            System.out.println("createWallet error"+ e.getMessage());
            throw  new RuntimeException("生成地址失敗!");
        }
    }

    /**
     * 位元組轉地址
     * @param pub
     * @return
     */
    private static String byteToAddress(byte[] pub) {
        Blake2b.Digest digest = Blake2b.Digest.newInstance(20);
        String hash = HexUtil.encodeHexStr(digest.digest(pub));

        //4.計算校驗和
        String pubKeyHash = "01" + HexUtil.encodeHexStr(digest.digest(pub));

        Blake2b.Digest blake2b3 = Blake2b.Digest.newInstance(4);
        String checksum = HexUtil.encodeHexStr(blake2b3.digest(HexUtil.decodeHex(pubKeyHash)));
        //5.生成地址

        return "f1" + Base32.encode(HexUtil.decodeHex(hash + checksum)).toLowerCase();
    }


    /**
     * 根據區塊鏈高度獲取區塊鏈資訊
     */
    public static ChainResult getChainTipSetByHeight(BigInteger heigth){
        try{
            String method = "Filecoin.ChainGetTipSetByHeight";
            List<Object> object = new ArrayList<>();
            object.add(heigth);
            object.add(null);
            Optional optional = FilHttpUtils.post(object,method);
            JSONObject dataJson = JSONObject.parseObject(String.valueOf(optional.get()));
            System.out.println("FilCoinUtil.getChainTipSetByHeight " + heigth + " | res:" + dataJson);
            ChainResult chainResult = chainJsonToChainResult(dataJson);
            return chainResult;
        }catch (Exception e){
            System.out.println("FilCoinUtil.getChainTipSetByHeight: " + heigth+ e.getMessage());
            throw  new RuntimeException("getChainTipSetByHeight error",e);
        }
    }

    /**
     * 區塊鏈json資料轉物件
     * @param jsonObject
     * @return
     */
    private static ChainResult chainJsonToChainResult(JSONObject jsonObject){
        JSONObject result = jsonObject.getJSONObject("result");
        BigInteger height = result.getBigInteger("Height");
        ArrayList<String> cidList = new ArrayList<>();
        ArrayList<String> parentCidList = new ArrayList<>();
        JSONArray cidJsonArr = result.getJSONArray("Cids");
        JSONArray blocksArr = result.getJSONArray("Blocks");
        if (cidJsonArr != null){
            for (Object o : cidJsonArr) {
                cn.hutool.json.JSONObject cidKy = new cn.hutool.json.JSONObject(o);
                String cid = cidKy.getStr("/");
                if (!StringUtils.isEmpty(cid)){
                    cidList.add(cid);
                }
            }
        }
        if (blocksArr != null && blocksArr.size() > 0){
            JSONArray cidArr =  JSONObject.parseObject(String.valueOf(blocksArr.get(0))).getJSONArray("Parents");
            if (cidArr != null){
                for (Object o : cidArr) {
                    String cid = new cn.hutool.json.JSONObject(o).getStr("/");
                    if (!StringUtils.isEmpty(cid)){
                        parentCidList.add(cid);
                    }
                }
            }
        }
        return ChainResult.builder().height(height).blockCidList(cidList).parentBlockCidList(parentCidList).build();
    }


    /**
     * 根據訊息cid獲取訊息詳情
     * @param cid 訊息cid
     */
    public static MessagesResult getMessageByCid(String cid){
        try{
            String method = "Filecoin.ChainGetMessage";
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("/", cid);
            List<Object> object = new ArrayList<>();
            object.add(jsonObject);
            Optional optional = FilHttpUtils.post(object,method);
            JSONObject dataJson = JSONObject.parseObject(String.valueOf(optional.get()));
            System.out.println(optional.get());
            System.out.println("FilCoinUtil.getTradeMessageByCid " + cid + " | res:" + dataJson);
            System.out.println(dataJson);
            MessagesResult messagesResult = messagesJsonToMessagesResult(dataJson.getJSONObject("result"));
            return messagesResult;
        }catch (Exception e){
            System.out.println("FilCoinUtil.getTradeMessageByCid: " + cid + e.getMessage());
            throw  new RuntimeException("獲取訊息詳情失敗",e);
        }
    }

    /**
     * 訊息json轉為訊息物件
     * @param jsonObject
     * @return
     */
    private static MessagesResult messagesJsonToMessagesResult(JSONObject jsonObject){
        return MessagesResult.builder().from(jsonObject.getString("From"))
                .to(jsonObject.getString("To"))
                .version(jsonObject.getInteger("Version"))
                .nonce(jsonObject.getInteger("Nonce"))
                .value(Convert.fromAtto(jsonObject.getBigInteger("Value").toString(), Convert.Unit.FIL))
                .gasLimit(jsonObject.getInteger("GasLimit"))
                .gasFeeCap(jsonObject.getBigInteger("GasFeeCap"))
                .gasPremium(jsonObject.getBigInteger("GasPremium"))
                .method(jsonObject.getInteger("Method"))
                .params(jsonObject.getString("Params"))
                .cid(jsonObject.getJSONObject("CID")
                        .getString("/"))
                .build();
    }


    /**
     * 根據區塊cid獲取區塊內所有訊息
     * @param blockCid 區塊id
     * @return
     */
    public static List<MessagesResult>  getMessagesByBlockCid(String blockCid){
        try{
            String method = "Filecoin.ChainGetBlockMessages";
            JSONObject _cid = new JSONObject();
            _cid.put("/", blockCid);
            List<Object> object = new ArrayList<>();
            object.add(_cid);
            Optional optional = FilHttpUtils.post(object,method);
            JSONObject dataJson = JSONObject.parseObject(String.valueOf(optional.get()));
            System.out.println("FilCoinUtil.getMessagesByBlockCid " + blockCid + " | res:" + dataJson);
            System.out.println(dataJson.toJSONString());
            ArrayList<MessagesResult> messagesResults = new ArrayList<>();
            JSONObject resultJson = dataJson.getJSONObject("result");
            if(resultJson == null){
                resultJson = new JSONObject();
            }
            JSONArray blsMessagesArr = resultJson.getJSONArray("BlsMessages");
            JSONArray secpkMessagesArr = resultJson.getJSONArray("SecpkMessages");
            if (blsMessagesArr != null){
                for (Object o : blsMessagesArr) {
                    messagesResults.add(messagesJsonToMessagesResult(JSONObject.parseObject(String.valueOf(o))));
                }
            }
            if (secpkMessagesArr != null){
                for (Object o : secpkMessagesArr) {
                    JSONObject secpkMessagesObj = JSONObject.parseObject(String.valueOf(o));
                    JSONObject message = secpkMessagesObj.getJSONObject("Message");
                    message.put("CID", secpkMessagesObj.get("CID"));
                    messagesResults.add(messagesJsonToMessagesResult(message));
                }
            }

            return messagesResults;

        }catch (Exception e){
            System.out.println("FilCoinUtil.getMessagesByBlockCid: " + blockCid + e.getMessage());
            throw  new RuntimeException("獲取區塊內所有訊息",e);
        }
    }



    /**
     * 獲取指定高度的所有訊息
     * @param height
     * @return
     */
    public static ChainMessagesResult getAllMessagesByHeight(BigInteger height) {
        ChainMessagesResult res = null;
        ChainResult chainTipSet = getChainTipSetByHeight(height);
        if (chainTipSet != null && chainTipSet.getBlockCidList() != null){
            res = ChainMessagesResult.builder().blockCidList(chainTipSet.getBlockCidList()).build();
            ArrayList<MessagesResult> messageList = new ArrayList<>();
            for (String blockCid : chainTipSet.getBlockCidList()) {
                List<MessagesResult> messagesList = getMessagesByBlockCid(blockCid);
                messageList.addAll(messagesList);
            }
            //訊息去重
            List list = messageList.stream().distinct().collect(Collectors.toList());
            res.setMessageList(list);
        }
        return res;
    }


    /**
     * 獲取nonce值
     * @param address  地址
     * @return
     */
    public static int getNonce(String address) {

        try{
            String method = FilecoinCnt.GET_NONCE;

            List<Object> object = new ArrayList<>();
            object.add(address);
            Optional optional = FilHttpUtils.post(object,method);
            JSONObject dataJson = JSONObject.parseObject(String.valueOf(optional.get()));
            System.out.println("FilCoinUtil.getNonce " + address + " | res:" + dataJson);
            return dataJson.getIntValue("result");

        }catch (Exception e){
            System.out.println("FilCoinUtil.getNonce: " + address + e.getMessage());
            throw  new RuntimeException("獲取Nonce失敗",e);
        }

    }


    /**
     * 獲取gas資訊
     * @param gas
     * @return
     */
    public  static GasResult getGas(GetGas gas)  {
        if (gas == null || StringUtils.isBlank(gas.getFrom())
                || StringUtils.isBlank(gas.getTo())
                || gas.getValue() == null) {
            throw new RuntimeException("paramter cannot be empty");
        }
        if (gas.getValue().compareTo(BigInteger.ZERO) < 1) {
            throw new RuntimeException("the transfer amount must be greater than 0 !" + JSONObject.toJSONString(gas));
        }
        List<Object> list = new ArrayList<>();
        JSONObject json = new JSONObject();
        json.put("From", gas.getFrom());
        json.put("To", gas.getTo());
        json.put("Value", gas.getValue().toString());
        list.add(json);
        list.add(null);
        list.add(null);
        Optional optional = FilHttpUtils.post(list,FilecoinCnt.GET_GAS);

        GasResult gasResult = null;
        try {
            JSONObject result = JSONObject.parseObject(String.valueOf(optional.get()));
            JSONObject jsonObject = result.getJSONObject("result");
            gasResult = GasResult.builder().gasFeeCap(jsonObject.getString("GasFeeCap"))
                    .gasLimit(jsonObject.getBigInteger("GasLimit"))
                    .gasPremium(jsonObject.getString("GasPremium")).build();
            return gasResult;
        } catch (Exception e) {
            System.out.println("FilCoinUtil.getGas " + e.getMessage());
            throw new RuntimeException("get gas error " ,e);
        }

    }




    public static SendResult send(Transaction transaction, String privatekey) throws RuntimeException {
        if (transaction == null || StringUtils.isBlank(transaction.getFrom())
                || StringUtils.isBlank(transaction.getTo())
                || StringUtils.isBlank(transaction.getGasFeeCap())
                || StringUtils.isBlank(transaction.getGasPremium())
                || StringUtils.isBlank(transaction.getValue())
                || transaction.getGasLimit() == null
                || transaction.getMethod() == null
                || transaction.getNonce() == null
                || StringUtils.isBlank(privatekey)) {
            throw new RuntimeException("parameter cnanot be empty");
        }
        BigInteger account = new BigInteger(transaction.getValue());
        if (account.compareTo(BigInteger.ZERO) < 1) {
            throw new RuntimeException("the transfer amount must be greater than 0");
        }
        byte[] cidHash = null;
        try {
            cidHash = TransactionHandler.transactionSerialize(transaction);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("transaction entity serialization failed");
        }
        //簽名
        ECKey ecKey = ECKey.fromPrivate(HexUtil.decodeHex(privatekey));
        String sing = Base64.encode(ecKey.sign(cidHash).toByteArray());

        List<Object> list = new ArrayList<>();
        JSONObject signatureJson = new JSONObject();
        JSONObject messageJson = JSONObject.parseObject(JSONObject.toJSONString(transaction));
        JSONObject json = new JSONObject();
        messageJson.put("version", 0);
        signatureJson.put("data", sing);
        signatureJson.put("type", 1);
        json.put("message", messageJson);
        json.put("signature", signatureJson);

        list.add(json);

        SendResult build = null;
        Optional optional = null;
        try {
             optional = FilHttpUtils.post(list,FilecoinCnt.BOARD_TRANSACTION);

            JSONObject executeJson = JSONObject.parseObject(String.valueOf(optional.get()));
            String result = executeJson.getJSONObject("result").getString("/");
            build = SendResult.builder().cid(result)
                    .nonce(transaction.getNonce()).build();
            return build;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("send error " + optional , e);
        }

    }

    public static  SendResult easySend(EasySend send)  {
        if (send == null || StringUtils.isBlank(send.getFrom())
                || StringUtils.isBlank(send.getTo())
                || StringUtils.isBlank(send.getPrivatekey())
                || send.getValue() == null) {
            throw new RuntimeException("parameter cannot be empty");
        }

        BigDecimal amount = Convert.toAtto(send.getValue(), Convert.Unit.FIL);
        BigInteger bigInteger = amount.toBigInteger();
        //獲取gas
        GasResult gas = getGas(GetGas.builder().from(send.getFrom())
                .to(send.getTo())
                .value(bigInteger).build());

        //獲取nonce
        int nonce = getNonce(send.getFrom());
        //拼裝交易引數
        Transaction transaction = Transaction.builder().from(send.getFrom())
                .to(send.getTo())
                .gasFeeCap(gas.getGasFeeCap())
                .gasLimit(gas.getGasLimit().longValue() * 2)
                .gasPremium(gas.getGasPremium())
                .method(0L)
                .nonce((long) nonce)
                .params("")
                .value(bigInteger.toString()).build();

        return send(transaction, send.getPrivatekey());
    }


    /**
     * 獲取訊息收據
     * @param messageCid  訊息id
     * @return
     */
    public static StateGetReceiptResult stateGetReceipt(String messageCid) {

        List<Object> list = new ArrayList<>();
        HashMap<String, String> cidParam = new HashMap<>(8);
        cidParam.put("/", messageCid);
        list.add(cidParam);
        list.add(null);

        StateGetReceiptResult res = null;
        JSONObject jsonObject = null;
        try {
            Optional optional = FilHttpUtils.post(list,FilecoinCnt.STATE_GET_RECEIPT);
            jsonObject = JSONObject.parseObject(String.valueOf(optional.get()));
            JSONObject result = jsonObject.getJSONObject("result");
            res = StateGetReceiptResult.builder().exitCode(result.getInteger("ExitCode"))
                    .messageReturn(result.getString("Return"))
                    .gasUsed(result.getBigInteger("GasUsed"))
                    .build();
            return res;
        } catch (Exception e) {
            System.out.println("stateGetReceipt error messgeid:" + messageCid + ",jsonObject=" + JSON.toJSONString(jsonObject) + e.getMessage());
            throw new RuntimeException("stateGetReceipt error " +  messageCid + ",jsonObject=" + JSON.toJSONString(jsonObject) + e.getMessage());
        }
    }


    public static  void main(String[] args){
        //獲取地址余額
        //System.out.println(getBalance("f1l3aboc6csauxuqrb2mftpvsjahuli4gxro6tllq"));
        //校驗地址
       // System.out.println(checkAddress("f1l3aboc6csauxuqrb2mftpvsjahuli4gxro6tll2"));
        //測驗生成地址
        //System.out.println(createWallet());


          //獲取某個高度的所有訊息(充值到賬)
//        ChainMessagesResult chainMessagesResult = getAllMessagesByHeight(BigInteger.valueOf(1142577L));
//        for(MessagesResult messagesResult:chainMessagesResult.getMessageList()){
//
//            //判斷訊息是否是交易資訊,等于0
//            if(messagesResult.getMethod().intValue() == 0) {
//                //校驗交易是否正常
//                StateGetReceiptResult stateGetReceiptResult = FilCoinUtil.stateGetReceipt(messagesResult.getCid());
//                if(stateGetReceiptResult.getExitCode().intValue() == 0 ) {
//                    //到賬地址
//                    String toAddress = messagesResult.getTo();
//                    //交易hash
//                    String hash = messagesResult.getCid();
//                    //todo 業務處理,充值到賬
//                }
//            }
//        }

        //測驗提幣上鏈
//        //私鑰
//        String privatekey = "fil秘鑰";
//        EasySend easySend = new EasySend();
//        //來源地址
//        easySend.setFrom("f1sle4slx2xqap7p2ehatextarj5nlgeilclgs723");
//        //目標地址
//        easySend.setTo("f1sle4slx2xqap7p2ehatextarj5nlgeilclgs7qi");
//        easySend.setPrivatekey(privatekey);
//        //轉賬金額
//        BigDecimal amount = new BigDecimal("0.0001");
//        easySend.setValue(amount);
//        System.out.println(easySend(easySend));



    }
}

如在使用的程序中,有問題,麻煩發資訊到郵箱408337459@qq.com

轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/303364.html

標籤:區塊鏈

上一篇:專案管理(PMP)認證介紹

下一篇:國際區塊鏈專利:中國螞蟻、平安、騰訊、復雜美位列前十

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • JAVA使用 web3j 進行token轉賬

    最近新學習了下區塊鏈這方面的知識,所學不多,給大家分享下。 # 1. 關于web3j web3j是一個高度模塊化,反應性,型別安全的Java和Android庫,用于與智能合約配合并與以太坊網路上的客戶端(節點)集成。 # 2. 準備作業 jdk版本1.8 引入maven <dependency> < ......

    uj5u.com 2020-09-10 03:03:06 more
  • 以太坊智能合約開發框架Truffle

    前言 部署智能合約有多種方式,命令列的瀏覽器的渠道都有,但往往跟我們程式員的風格不太相符,因為我們習慣了在IDE里寫了代碼然后打包運行看效果。 雖然現在IDE中已經存在了Solidity插件,可以撰寫智能合約,但是部署智能合約卻要另走他路,沒辦法進行一個快捷的部署與測驗。 如果團隊管理的區塊節點多、 ......

    uj5u.com 2020-09-10 03:03:12 more
  • 谷歌二次驗證碼成為區塊鏈專用安全碼,你怎么看?

    前言 谷歌身份驗證器,前些年大家都比較陌生,但隨著國內互聯網安全的加強,它越來越多地出現在大家的視野中。 比較廣泛接觸的人群是國際3A游戲愛好者,游戲盜號現象嚴重+國外賬號安全應用廣泛,這類游戲一般都會要求用戶系結名為“兩步驗證”、“雙重驗證”等,平臺一般都推薦用谷歌身份驗證器。 后來區塊鏈業務風靡 ......

    uj5u.com 2020-09-10 03:03:17 more
  • 密碼學DAY1

    目錄 ##1.1 密碼學基本概念 密碼在我們的生活中有著重要的作用,那么密碼究竟來自何方,為何會產生呢? 密碼學是網路安全、資訊安全、區塊鏈等產品的基礎,常見的非對稱加密、對稱加密、散列函式等,都屬于密碼學范疇。 密碼學有數千年的歷史,從最開始的替換法到如今的非對稱加密演算法,經歷了古典密碼學,近代密 ......

    uj5u.com 2020-09-10 03:03:50 more
  • 密碼學DAY1_02

    目錄 ##1.1 ASCII編碼 ASCII(American Standard Code for Information Interchange,美國資訊交換標準代碼)是基于拉丁字母的一套電腦編碼系統,主要用于顯示現代英語和其他西歐語言。它是現今最通用的單位元組編碼系統,并等同于國際標準ISO/IE ......

    uj5u.com 2020-09-10 03:04:50 more
  • 密碼學DAY2

    ##1.1 加密模式 加密模式:https://docs.oracle.com/javase/8/docs/api/javax/crypto/Cipher.html ECB ECB : Electronic codebook, 電子密碼本. 需要加密的訊息按照塊密碼的塊大小被分為數個塊,并對每個塊進 ......

    uj5u.com 2020-09-10 03:05:42 more
  • NTP時鐘服務器的特點(京準電子)

    NTP時鐘服務器的特點(京準電子) NTP時鐘服務器的特點(京準電子) 京準電子官V——ahjzsz 首先對時間同步進行了背景介紹,然后討論了不同的時間同步網路技術,最后指出了建立全球或區域時間同步網存在的問題。 一、概 述 在通信領域,“同步”概念是指頻率的同步,即網路各個節點的時鐘頻率和相位同步 ......

    uj5u.com 2020-09-10 03:05:47 more
  • 標準化考場時鐘同步系統推進智能化校園建設

    標準化考場時鐘同步系統推進智能化校園建設 標準化考場時鐘同步系統推進智能化校園建設 安徽京準電子科技官微——ahjzsz 一、背景概述隨著教育事業的快速發展,學校建設如雨后春筍,隨之而來的學校教育、管理、安全方面的問題成了學校管理人員面臨的最大的挑戰,這些問題同時也是學生家長所擔心的。為了讓學生有更 ......

    uj5u.com 2020-09-10 03:05:51 more
  • 位元幣入門

    引言 位元幣基本結構 位元幣基礎知識 1)哈希演算法 2)非對稱加密技術 3)數字簽名 4)MerkleTree 5)哪有位元幣,有的是UTXO 6)位元幣挖礦與共識 7)區塊驗證(共識) 總結 引言 上一篇我們已經知道了什么是區塊鏈,此篇說一下區塊鏈的第一個應用——位元幣。其實先有位元幣,后有的區塊 ......

    uj5u.com 2020-09-10 03:06:15 more
  • 北斗對時服務器(北斗對時設備)電力系統應用

    北斗對時服務器(北斗對時設備)電力系統應用 北斗對時服務器(北斗對時設備)電力系統應用 京準電子科技官微(ahjzsz) 中國北斗衛星導航系統(英文名稱:BeiDou Navigation Satellite System,簡稱BDS),因為是目前世界范圍內唯一可以大面積提供免費定位服務的系統,所以 ......

    uj5u.com 2020-09-10 03:06:20 more
最新发布
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:46:47 more
  • Hyperledger Fabric 使用 CouchDB 和復雜智能合約開發

    在上個實驗中,我們已經實作了簡單智能合約實作及客戶端開發,但該實驗中智能合約只有基礎的增刪改查功能,且其中的資料管理功能與傳統 MySQL 比相差甚遠。本文將在前面實驗的基礎上,將 Hyperledger Fabric 的默認資料庫支持 LevelDB 改為 CouchDB 模式,以實作更復雜的資料... ......

    uj5u.com 2023-04-16 07:28:31 more
  • .NET Core 波場鏈離線簽名、廣播交易(發送 TRX和USDT)筆記

    Get Started NuGet You can run the following command to install the Tron.Wallet.Net in your project. PM> Install-Package Tron.Wallet.Net 配置 public reco ......

    uj5u.com 2023-04-14 08:08:00 more
  • DKP 黑客分析——不正確的代幣對比率計算

    概述: 2023 年 2 月 8 日,針對 DKP 協議的閃電貸攻擊導致該協議的用戶損失了 8 萬美元,因為 execute() 函式取決于 USDT-DKP 對中兩種代幣的余額比率。 智能合約黑客概述: 攻擊者的交易:0x0c850f,0x2d31 攻擊者地址:0xF38 利用合同:0xf34ad ......

    uj5u.com 2023-04-07 07:46:09 more
  • Defi開發簡介

    Defi開發簡介 介紹 Defi是去中心化金融的縮寫, 是一項旨在利用區塊鏈技術和智能合約創建更加開放,可訪問和透明的金融體系的運動. 這與傳統金融形成鮮明對比,傳統金融通常由少數大型銀行和金融機構控制 在Defi的世界里,用戶可以直接從他們的電腦或移動設備上訪問廣泛的金融服務,而不需要像銀行或者信 ......

    uj5u.com 2023-04-05 08:01:34 more
  • solidity簡單的ERC20代幣實作

    // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.0 <0.9.0; import "hardhat/console.sol"; //ERC20 同質化代幣,每個代幣的本質或性質都是相同 //ETH 是原生代幣,它不是ERC20代幣, ......

    uj5u.com 2023-03-21 07:56:29 more
  • solidity 參考型別修飾符memory、calldata與storage 常量修飾符C

    在solidity語言中 參考型別修飾符(參考型別為存盤空間不固定的數值型別) memory、calldata與storage,它們只能修飾參考型別變數,比如字串、陣列、位元組等... memory 適用于方法傳參、返參或在方法體內使用,使用完就會清除掉,釋放記憶體 calldata 僅適用于方法傳參 ......

    uj5u.com 2023-03-08 07:57:54 more
  • solidity注解標簽

    在solidity語言中 注釋符為// 注解符為/* 內容*/ 或者 是 ///內容 注解中含有這幾個標簽給予我們使用 @title 一個應該描述合約/介面的標題 contract, library, interface @author 作者的名字 contract, library, interf ......

    uj5u.com 2023-03-08 07:57:49 more
  • 評價指標:相似度、GAS消耗

    【代碼注釋自動生成方法綜述】 這些評測指標主要來自機器翻譯和文本總結等研究領域,可以評估候選文本(即基于代碼注釋自動方法而生成)和參考文本(即基于手工方式而生成)的相似度. BLEU指標^[^?88^^?^]^:其全稱是bilingual evaluation understudy.該指標是最早用于 ......

    uj5u.com 2023-02-23 07:27:39 more
  • 基于NOSTR協議的“公有制”版本的Twitter,去中心化社交軟體Damus

    最近,一個幽靈,Web3的幽靈,在網路游蕩,它叫Damus,這玩意詮釋了什么叫做病毒式營銷,滑稽的是,一個Web3產品卻在Web2的產品鏈上瘋狂傳銷,各方大佬紛紛為其背書,到底發生了什么?Damus的葫蘆里,賣的是什么藥? 注冊和簡單實用 很少有什么產品在用戶注冊環節會有什么噱頭,但Damus確實出 ......

    uj5u.com 2023-02-05 06:48:39 more