1. 交易所接入

1.1 节点搭建

  交易所节点搭建步骤和基本操作命令请参考 《开发者指南 3.4 节点搭建》《开发者指南 3.5 基本命令》。在测试网测试无误后,联系我们(邮箱地址:developer@sdchain.io)获取正式网的配置文件,并告知服务商节点IP。配置方式如下:

如果是在当前服务器上切换到正式网,需要先清除测试网的账本:

cd /usr/local/sdchaind
./sdchaind stop                    
rm –rf ./db

再配置正式网配置文件:

mv official/SDChain-Core.cfg /usr/local/sdchaind/   
mv official/validators.txt /usr/local/sdchaind/

完成配置后启动运行,并验证是否启动成功。

1.2 代码示例

const exchangeAccount = "6BCNL443M1Qhw6i42b2yyFFpHPgEkACiuo";
const exchangePrivateKey = "";
const safeBlockNum = 30;
const baseDrops = 1000000;

监听充币

// Listening for deposits
async function deposits() {
    while (true) {
        try {
            // Get last validated block
            const lastBlockNum = await getLastBlockNum();
            // Get last block from exchange db
            const syncedBlockNum = await getSyncedBlockNum();
            const minBlockNum = syncedBlockNum + 1;
            const maxBlockNum = lastBlockNum - safeBlockNum;
            // Block not increase
            if (maxBlockNum < minBlockNum) {
                tools.sleep(20000);
                continue;
            }
            // Get all payment transactions by block
            const payments = await getPayments(minBlockNum, maxBlockNum);
            for (i = 0; i < payments.length; i++) {
                const tx = payments[i];
                const hash = tx.hash;
                const fromAccount = tx.Account;
                const toAccount = tx.Destination;
                // 1SDA=1000000Drops
                const amount = dropsToBase(tx.Amount);
                // Hex2String
                const memo = parseMemo(tx.Memos);

                // Valid payments
                await checkAndSaveToDB(hash, fromAccount, toAccount, amount, memo);
            }
            updateSyncedBlockNum(maxBlockNum);
        } catch (e) {
            // Log something
            console.log(e);
            await tools.sleep(10000);
        }

    }
}

//Get last validated block
async function getLastBlockNum() {
    let response = null;
    try {
        response = await request({
            uri: rpcUrl,
            method: "POST",
            body: {
                "method": "ledger",
                "params": [
                    {
                        "ledger_index": "validated",
                        "accounts": false,
                        "full": false,
                        "transactions": false,
                        "expand": false,
                        "owner_funds": false
                    }
                ]
            },
            json: true
        });
    } catch (e) {
        // Log something
        console.log(e);
        return null;
    }
    // Submit success
    if (response && response.result && response.result.status == "success") {
        return response.result.ledger_index;
    } else {
        // log something
        console.log(response.result);
        return null;
    }
}

// Get all payment transactions by block
async function getPayments(minBlockNum, maxBlockNum) {
    const payments = [];
    try {
        let marker = null;
        while (true) {
            const response = await request({
                uri: rpcUrl,
                method: "POST",
                body: {
                    "method": "account_tx",
                    "params": [
                        {
                            "account": exchangeAccount,
                            "binary": false,
                            "forward": false,
                            "ledger_index_min": minBlockNum,
                            "ledger_index_max": maxBlockNum,
                            "marker": marker,
                            "limit": 1000
                        }
                    ]
                },
                json: true
            });
            result = response.result;
            marker = result.marker;
            for (i = 0; i < result.transactions.length; i++) {
                const txInfo = result.transactions[i];
                // Failed transaction
                if (txInfo.meta.TransactionResult != "tesSUCCESS") {
                    continue;
                }
                // Not payment
                if (txInfo.tx.TransactionType != "Payment") {
                    continue;
                }
                payments.push(txInfo.tx);
            }
            // No more transactions
            if (!marker) {
                break;
            }
        }
        return payments;
    } catch (e) {
        // Log something
        console.log(e);
        return null;
    }
}

// Hex memo to string
function parseMemo(memos) {
    if (memos.length == 0) {
        return null;
    }
    const hexMemo = memos[0].Memo.MemoData;
    const memo = new Buffer(hexMemo, "hex").toString("utf-8");
    return memo;
}

function dropsToBase(amount) {
    return (new BigNumber(amount)).dividedBy(baseDrops).toString()
}

提币和提币校验

// User withdraw
async function withdraw(toAccount, amount, memo) {
    const requestParams = {
        "offline": false,
        "secret": exchangePrivateKey,
        "tx_json": {
            "Account": exchangeAccount,
            "Amount": baseToDrops(amount),
            "Destination": toAccount,
            "TransactionType": "Payment"
        }
    };
    if (memo) {
        // Memo must be hex
        const hexType = new Buffer("type").toString("hex");
        const hexMemo = new Buffer(memo).toString("hex");

        requestParams.tx_json.Memos = [];
        requestParams.tx_json.Memos.push({
            "Memo": {
                "MemoType": hexType,
                "MemoData": hexMemo
            }
        });
    }
    const response = await request({
        uri: rpcUrl,
        method: "POST",
        body: {
            "method": "submit",
            "params": [
                requestParams
            ]
        },
        json: true
    });
    const result = response.result;
    if (result.status == "success" && result.engine_result == "tesSUCCESS") {
        // Submit success wait validate
        return result.tx_json.hash;
    } else {
        // Submit error
        // Log something
        console.log(JSON.stringify(result));
    }
    return null;
}

// Check withdraw status
async function withdrawCheck(hash) {
    const response = await request({
        uri: rpcUrl,
        method: "POST",
        body: {
            "method": "tx",
            "params": [
                {
                    "transaction": hash,
                    "binary": false
                }
            ]
        },
        json: true
    });
    const result = response.result;
    if (result.status == "success") {
        if (result.validated && result.meta) {
            if (result.meta.TransactionResult == "tesSUCCESS") {
                // Success
                return 1;
            } else {
                // Faild transaction
                return -1;
            }
        } else {
            // Not completed
            return 0;
        }
    } else {
        // Faild transaction
        return -1;
    }

}

function baseToDrops(amount) {
    return (new BigNumber(amount)).multipliedBy(baseDrops).toString()
}

results matching ""

    No results matching ""