Bytom 储蓄分红 DAPP 开发指南

简介: 储蓄分红合约指的是项目方发起了一个锁仓计划(即储蓄合约和取现合约),用户可以在准备期自由选择锁仓金额参与该计划,等到锁仓到期之后还可以自动获取锁仓的利润。

储蓄分红DAPP

储蓄分红合约简介

储蓄分红合约指的是项目方发起了一个锁仓计划(即储蓄合约和取现合约),用户可以在准备期自由选择锁仓金额参与该计划,等到锁仓到期之后还可以自动获取锁仓的利润。用户可以在准备期内(dueBlockHeight)参与储蓄,按照合约规定可以 1:1 获取同等数量的储蓄票据资产,同时用户锁仓的资产(deposit)将放到取现合约中,并且项目方是无法动用的,等到锁仓期限(expireBlockHeight)一到,用户便可以调用取现合约将自己储蓄的资产连本待息一同取出来。其示意图如下:

从上图中可以看出,项目方发布了一个利润为20%的锁仓项目,其中储蓄合约FixedLimitCollect锁定了1000个票据资产(bill),同时项目方将200个储蓄资产(deposit)锁定到利息合约中。待项目方发布完合约之后,所有用户便可以参与了。例如上图中user1调用合约储蓄了500,这500个储蓄资产将被锁定在取现合约FixedLimitProfit中,同时user1获得了500个票据资产,剩余找零的资产将继续锁定在储蓄合约FixedLimitCollect中,以此类推,user2user3也是相同的流程,直到储蓄合约没有资产为止。取现合约FixedLimitProfit跟储蓄合约的模型大致相同,只是取现合约是由多个UTXO组成的,用户在取现的时候可以并行操作。但是如果合约中的面值不能支持用户一次性取现的话,需要分多次提取。例如user1拥有500个票据资产,而可以获得的本息总额为600,但是取现的UTXO面值为500,那么user1一次最多只能取500,剩下的100需要再构造一笔交易来提现。

合约源代码

// 储蓄合约
import "./FixedLimitProfit"
contract FixedLimitCollect(assetDeposited: Asset,
                        totalAmountBill: Amount,
                        totalAmountCapital: Amount,
                        dueBlockHeight: Integer,
                        expireBlockHeight: Integer,
                        additionalBlockHeight: Integer,
                        banker: Program,
                        bankerKey: PublicKey) locks billAmount of billAsset {
    clause collect(amountDeposited: Amount, saver: Program) {
        verify below(dueBlockHeight)
        verify amountDeposited <= billAmount && totalAmountBill <= totalAmountCapital
        define sAmountDeposited: Integer = amountDeposited/100000000
        define sTotalAmountBill: Integer = totalAmountBill/100000000
        verify sAmountDeposited > 0 && sTotalAmountBill > 0
        if amountDeposited < billAmount {
            lock amountDeposited of assetDeposited with FixedLimitProfit(billAsset, totalAmountBill, totalAmountCapital, expireBlockHeight, additionalBlockHeight, banker, bankerKey)
            lock amountDeposited of billAsset with saver
            lock billAmount-amountDeposited of billAsset with FixedLimitCollect(assetDeposited, totalAmountBill, totalAmountCapital, dueBlockHeight, expireBlockHeight, additionalBlockHeight, banker, bankerKey)
        } else {
            lock amountDeposited of assetDeposited with FixedLimitProfit(billAsset, totalAmountBill, totalAmountCapital, expireBlockHeight, additionalBlockHeight, banker, bankerKey)
            lock billAmount of billAsset with saver
        }
    }
    clause cancel(bankerSig: Signature) {
        verify above(dueBlockHeight)
        verify checkTxSig(bankerKey, bankerSig)
        unlock billAmount of billAsset
    }
}
// 取现合约(本金加利息)
contract FixedLimitProfit(assetBill: Asset,
                        totalAmountBill: Amount,
                        totalAmountCapital: Amount,
                        expireBlockHeight: Integer,
                        additionalBlockHeight: Integer,
                        banker: Program,
                        bankerKey: PublicKey) locks capitalAmount of capitalAsset {
    clause profit(amountBill: Amount, saver: Program) {
        verify above(expireBlockHeight)
        define sAmountBill: Integer = amountBill/100000000
        define sTotalAmountBill: Integer = totalAmountBill/100000000
        verify sAmountBill > 0 && sTotalAmountBill > 0 && amountBill < totalAmountBill
        define gain: Integer = totalAmountCapital*sAmountBill/sTotalAmountBill
        verify gain > 0 && gain <= capitalAmount
        if gain < capitalAmount {
            lock amountBill of assetBill with banker
            lock gain of capitalAsset with saver
            lock capitalAmount - gain of capitalAsset with FixedLimitProfit(assetBill, totalAmountBill, totalAmountCapital, expireBlockHeight, additionalBlockHeight, banker, bankerKey)
        } else {
            lock amountBill of assetBill with banker
            lock capitalAmount of capitalAsset with saver
        }
    }
    clause cancel(bankerSig: Signature) {
        verify above(additionalBlockHeight)
        verify checkTxSig(bankerKey, bankerSig)
        unlock capitalAmount of capitalAsset
    }
}

合约的源代码说明可以具体参考Equity合约介绍.

注意事项:

  • 时间期限不是具体的时间,而是通过区块高度来大概估算的(平均区块时间间隔大概为2.5分钟)
  • 比原的精度是8, 即 1BTM = 100000000 neu,正常情况下参与计算都是以neu为单位的,然而虚拟机的int64类型的最大值是9223372036854775807,为了避免数值太大导致计算溢出,所以对计算的金额提出了金额限制(即amountBill/100000000
  • 另外clause cancel是项目方的管理方法,如果储蓄或者取现没有满额,项目方也可以回收剩余的资产

编译并实例化合约

编译Equity合约可以参考一下Equity编译器的介绍说明。假如储蓄合约FixedLimitCollect的参数如下:

assetDeposited          :c6b12af8326df37b8d77c77bfa2547e083cbacde15cc48da56d4aa4e4235a3ee
totalAmountBill         :10000000000
totalAmountCapital      :20000000000
dueBlockHeight          :1070
expireBlockHeight       :1090
additionalBlockHeight   :1100
banker                  :0014dedfd406c591aa221a047a260107f877da92fec5
bankerKey               :055539eb36abcaaf127c63ae20e3d049cd28d0f1fe569df84da3aedb018ca1bf

其中bankerKey是管理员的publicKey,可以通过比原链的接口list-pubkeys来获取,注意管理员需要保存一下对应的rootXpubPath,否则无法正确调用clause cancel

实例化合约命令如下:

// 储蓄合约
./equity FixedLimitCollect --instance c6b12af8326df37b8d77c77bfa2547e083cbacde15cc48da56d4aa4e4235a3ee 10000000000 20000000000 1070 1090 1100 0014dedfd406c591aa221a047a260107f877da92fec5 055539eb36abcaaf127c63ae20e3d049cd28d0f1fe569df84da3aedb018ca1bf

// 取现合约
./equity FixedLimitProfit --instance c6b12af8326df37b8d77c77bfa2547e083cbacde15cc48da56d4aa4e4235a3ee 10000000000 20000000000 1090 1100 0014dedfd406c591aa221a047a260107f877da92fec5 055539eb36abcaaf127c63ae20e3d049cd28d0f1fe569df84da3aedb018ca1bf

发布合约交易

发布合约交易即将资产锁定到合约中。由于目前无法在比原的dashboard上构造合约交易,所以需要借助外部工具来发送合约交易,比如postman。按照上述示意图所示,项目方需要发布1000个储蓄资产的储蓄合约和200个利息资产取现合约。假设项目方需要发布1000个储蓄资产(假如精度为8,那么1000个在比原链中表示为100000000000)的锁仓合约,那么他需要将对应数量的票据锁定在储蓄合约中,其交易模板如下:

{
  "base_transaction": null,
  "actions": [
    {
      "account_id": "0ILGLSTC00A02",
      "amount": 20000000,
      "asset_id": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
      "type": "spend_account"
    },
    {
      "account_id": "0ILGLSTC00A02",
      "amount": 100000000000,
      "asset_id": "13016eff73ffb7539a69e122f80f5c1cc94446773ac3f64dec290429f87e73b3",
      "type": "spend_account"
    },
    {
      "amount": 100000000000,
      "asset_id": "13016eff73ffb7539a69e122f80f5c1cc94446773ac3f64dec290429f87e73b3",
      "control_program": "20055539eb36abcaaf127c63ae20e3d049cd28d0f1fe569df84da3aedb018ca1bf160014dedfd406c591aa221a047a260107f877da92fec5024c04024204022e040500c817a8040500e40b540220c6b12af8326df37b8d77c77bfa2547e083cbacde15cc48da56d4aa4e4235a3ee4d3b02597a642f0200005479cda069c35b797ca153795579a19a695a790400e1f5059653790400e1f505967c00a07c00a09a69c35b797c9f9161644d010000005b79c2547951005e79895d79895c79895b7989597989587989537a894caa587a649e0000005479cd9f6959790400e1f5059653790400e1f505967800a07800a09a5c7956799f9a6955797b957c96c37800a052797ba19a69c3787c9f91616487000000005b795479515b79c1695178c2515d79c16952c3527994c251005d79895c79895b79895a79895979895879895779895679890274787e008901c07ec1696399000000005b795479515b79c16951c3c2515d79c16963aa000000557acd9f69577a577aae7cac890274787e008901c07ec169515b79c2515d79c16952c35c7994c251005d79895c79895b79895a79895979895879895779895679895579890274787e008901c07ec169632a020000005b79c2547951005e79895d79895c79895b7989597989587989537a894caa587a649e0000005479cd9f6959790400e1f5059653790400e1f505967800a07800a09a5c7956799f9a6955797b957c96c37800a052797ba19a69c3787c9f91616487000000005b795479515b79c1695178c2515d79c16952c3527994c251005d79895c79895b79895a79895979895879895779895679890274787e008901c07ec1696399000000005b795479515b79c16951c3c2515d79c16963aa000000557acd9f69577a577aae7cac890274787e008901c07ec16951c3c2515d79c169633b020000547acd9f69587a587aae7cac747800c0",
      "type": "control_program"
    }
  ],
  "ttl": 0,
  "time_range": 1521625823
}

合约交易成功后,合约control_program对应的UTXO将会被所有用户查询到,使用比原链的接口list-unspent-outputs即可查询。

此外,开发者需要存储一下合约UTXOassetIDprogram,以便在DAPP的前端页面的config配置文件和bufferserver缓冲服务器中调用。如上所示:

// 储蓄合约
assetID:13016eff73ffb7539a69e122f80f5c1cc94446773ac3f64dec290429f87e73b3
program:20055539eb36abcaaf127c63ae20e3d049cd28d0f1fe569df84da3aedb018ca1bf160014dedfd406c591aa221a047a260107f877da92fec5024c04024204022e040500c817a8040500e40b540220c6b12af8326df37b8d77c77bfa2547e083cbacde15cc48da56d4aa4e4235a3ee4d3b02597a642f0200005479cda069c35b797ca153795579a19a695a790400e1f5059653790400e1f505967c00a07c00a09a69c35b797c9f9161644d010000005b79c2547951005e79895d79895c79895b7989597989587989537a894caa587a649e0000005479cd9f6959790400e1f5059653790400e1f505967800a07800a09a5c7956799f9a6955797b957c96c37800a052797ba19a69c3787c9f91616487000000005b795479515b79c1695178c2515d79c16952c3527994c251005d79895c79895b79895a79895979895879895779895679890274787e008901c07ec1696399000000005b795479515b79c16951c3c2515d79c16963aa000000557acd9f69577a577aae7cac890274787e008901c07ec169515b79c2515d79c16952c35c7994c251005d79895c79895b79895a79895979895879895779895679895579890274787e008901c07ec169632a020000005b79c2547951005e79895d79895c79895b7989597989587989537a894caa587a649e0000005479cd9f6959790400e1f5059653790400e1f505967800a07800a09a5c7956799f9a6955797b957c96c37800a052797ba19a69c3787c9f91616487000000005b795479515b79c1695178c2515d79c16952c3527994c251005d79895c79895b79895a79895979895879895779895679890274787e008901c07ec1696399000000005b795479515b79c16951c3c2515d79c16963aa000000557acd9f69577a577aae7cac890274787e008901c07ec16951c3c2515d79c169633b020000547acd9f69587a587aae7cac747800c0

// 取现合约
assetID:c6b12af8326df37b8d77c77bfa2547e083cbacde15cc48da56d4aa4e4235a3ee
program:20055539eb36abcaaf127c63ae20e3d049cd28d0f1fe569df84da3aedb018ca1bf160014dedfd406c591aa221a047a260107f877da92fec5024c040242040500c817a8040500e40b540220c6b12af8326df37b8d77c77bfa2547e083cbacde15cc48da56d4aa4e4235a3ee4caa587a649e0000005479cd9f6959790400e1f5059653790400e1f505967800a07800a09a5c7956799f9a6955797b957c96c37800a052797ba19a69c3787c9f91616487000000005b795479515b79c1695178c2515d79c16952c3527994c251005d79895c79895b79895a79895979895879895779895679890274787e008901c07ec1696399000000005b795479515b79c16951c3c2515d79c16963aa000000557acd9f69577a577aae7cac747800c0

储蓄分红DAPP架构模型

比原链的DAPP总体框架模型描述了DAPP的大致结构模型,结合储蓄分红合约案例,其具体流程如下:

DAPP前端

储蓄分红合约前端逻辑处理流程大致如下:

  • 1)调用插件

    比原的chrome插件源码位于Bytom-JS-SDK,开发比原DAPP时调用插件的说明可以参考Dapp Developer Guide

  • 2)配置合约参数

    Dapp demo中需要配置实例化的参数为assetDepositedtotalAmountBilltotalAmountCapitaldueBlockHeightexpireBlockHeightadditionalBlockHeightbankerbankerKey。其前端配置文件为configure.json.js

    var config = {
        "solonet": {
            "depositProgram": "2091194ddbf3614cafbadb1274c33e61afd4d5044c6ec4c30f8202980199c30083160014c800033d5e94de5f22e23a6d3cbeaed87b55bd640600204aa9d101050010a5d4e8203310d9951697418af3cdbe7a9cdde1dc49bb5439503dacb33828d6c9ef5af5a24dfc01567a64f5010000c358797ca153795579a19a6957790400e1f5059653790400e1f505967c00a07c00a09a69c358797c9f91616429010000005879c2547951005b79895a7989597989587989537a894c9a567a649300000057790400e1f5059653790400e1f505967800a07800a09a5a7956799f9a6955797b957c96c37800a052797ba19a69c3787c9f9161647c0000000059795479515979c1695178c2515b79c16952c3527994c251005b79895a79895979895879895779895679890274787e008901c07ec169638e0000000059795479515979c16951c3c2515b79c169639a000000567a567aae7cac890274787e008901c07ec169515879c2515a79c16952c3597994c251005a79895979895879895779895679895579890274787e008901c07ec16963f0010000005879c2547951005b79895a7989597989587989537a894c9a567a649300000057790400e1f5059653790400e1f505967800a07800a09a5a7956799f9a6955797b957c96c37800a052797ba19a69c3787c9f9161647c0000000059795479515979c1695178c2515b79c16952c3527994c251005b79895a79895979895879895779895679890274787e008901c07ec169638e0000000059795479515979c16951c3c2515b79c169639a000000567a567aae7cac890274787e008901c07ec16951c3c2515a79c16963fc010000567a567aae7cac747800c0",
            "profitProgram": "2091194ddbf3614cafbadb1274c33e61afd4d5044c6ec4c30f8202980199c30083160014c800033d5e94de5f22e23a6d3cbeaed87b55bd640600204aa9d101050010a5d4e820666f298d34806a6db0528c3b3d081bc00fa58aa393e7c42f90d67eb7db2a524f4c9a567a649300000057790400e1f5059653790400e1f505967800a07800a09a5a7956799f9a6955797b957c96c37800a052797ba19a69c3787c9f9161647c0000000059795479515979c1695178c2515b79c16952c3527994c251005b79895a79895979895879895779895679890274787e008901c07ec169638e0000000059795479515979c16951c3c2515b79c169639a000000567a567aae7cac747800c0",
            "assetDeposited": "3310d9951697418af3cdbe7a9cdde1dc49bb5439503dacb33828d6c9ef5af5a2",
            "assetBill": "666f298d34806a6db0528c3b3d081bc00fa58aa393e7c42f90d67eb7db2a524f",
            "totalAmountBill": 1000000000000,
            "totalAmountCapital": 2000000000000,
            "dueBlockHeight": 0,
            "expireBlockHeight": 0,
            "banker": "0014c800033d5e94de5f22e23a6d3cbeaed87b55bd64",
            "gas": 0.4
        },
        "testnet":{
            "depositProgram": "20f39af759065598406ca988f0dd79af9175dd7adcbe019317a2d605578b1597ac1600147211ec12410ce8bd0d71cab0a29be3ea61c71eb103c8260203da240203da2402060080f420e6b50600407a10f35a2000d38a1c946e8cba1a69493240f281cd925002a43b81f516c4391b5fb2ffdacd4d4302597a64370200005479cda069c35b790400e1f5059600a05c797ba19a53795579a19a695a790400e1f5059653790400e1f505967800a07800a09a6955797b957c9600a069c35b797c9f9161645b010000005b79c2547951005e79895d79895c79895b7989597989587989537a894ca4587a64980000005479cd9f6959790400e1f5059653790400e1f505967800a07800a09a5c7956799f9a6955797b957c967600a069c3787c9f91616481000000005b795479515b79c1695178c2515d79c16952c3527994c251005d79895c79895b79895a79895979895879895779895679890274787e008901c07ec1696393000000005b795479515b79c16951c3c2515d79c16963a4000000557acd9f69577a577aae7cac890274787e008901c07ec169515b79c2515d79c16952c35c7994c251005d79895c79895b79895a79895979895879895779895679895579890274787e008901c07ec1696332020000005b79c2547951005e79895d79895c79895b7989597989587989537a894ca4587a64980000005479cd9f6959790400e1f5059653790400e1f505967800a07800a09a5c7956799f9a6955797b957c967600a069c3787c9f91616481000000005b795479515b79c1695178c2515d79c16952c3527994c251005d79895c79895b79895a79895979895879895779895679890274787e008901c07ec1696393000000005b795479515b79c16951c3c2515d79c16963a4000000557acd9f69577a577aae7cac890274787e008901c07ec16951c3c2515d79c1696343020000547acd9f69587a587aae7cac747800c0",
            "profitProgram": "20f39af759065598406ca988f0dd79af9175dd7adcbe019317a2d605578b1597ac1600147211ec12410ce8bd0d71cab0a29be3ea61c71eb103c8260203da2402060080f420e6b50600407a10f35a20f855baf98778a892bad0371f5afca845191824dc8584585d566fbbc8ef1f304c4ca4587a64980000005479cd9f6959790400e1f5059653790400e1f505967800a07800a09a5c7956799f9a6955797b957c967600a069c3787c9f91616481000000005b795479515b79c1695178c2515d79c16952c3527994c251005d79895c79895b79895a79895979895879895779895679890274787e008901c07ec1696393000000005b795479515b79c16951c3c2515d79c16963a4000000557acd9f69577a577aae7cac747800c0",
            "assetDeposited": "00d38a1c946e8cba1a69493240f281cd925002a43b81f516c4391b5fb2ffdacd",
            "assetBill": "f855baf98778a892bad0371f5afca845191824dc8584585d566fbbc8ef1f304c",
            "totalAmountBill": 100000000000000,
            "totalAmountCapital": 200000000000000,
            "dueBlockHeight": 140506,
            "expireBlockHeight": 140506,
            "banker": "00147211ec12410ce8bd0d71cab0a29be3ea61c71eb1",
            "gas": 0.4
        }
    }
  • 3)前端预计算处理

    以储蓄合约FixedLimitCollect为例,前端需要对该合约进行verify语句的预判断逻辑,以防用户输入参数之后执行失败。此外,合约中billAmount of billAsset表示锁定的资产和数量,而billAmountbillAssetutxohash都是储存在缓冲服务器的数据表里面,因此前端需要调用list-utxo查找与该资产assetprogram相关的所有未花费的utxo。 具体可以参考DAPP DEMO前端案例

  • 4)交易组成

    比原的交易是多输入多输出的模板结构,如果合约中包含了多个lockunlock语句,那么就需要用户构造多输入多输出的交易模板,同时,构造交易还需要根据lock语句或unlock语句来变换。交易构造具体可以参考储蓄合约交易模型取现合约交易模型的前端源代码。

    • 交易input结构如下:

    spendUTXOAction(utxohash)表示花费的合约utxo,其中utxohash表示合约UTXOhash,而spendWalletAction(amount, Constant.assetDeposited)表示用户输入的储蓄或取现的数量(仅包含中需要资产交换的合约中),而资产类型则由前端固定。

    export function spendUTXOAction(utxohash){
        return {
            "type": "spend_utxo",
            "output_id": utxohash
        }
    }
    
    export function spendWalletAction(amount, asset){
        return {
            "amount": amount,
            "asset": asset,
            "type": "spend_wallet"
        }
    }
    
    const input = []
    input.push(spendUTXOAction(utxohash))
    input.push(spendWalletAction(amount, Constant.assetDeposited))
    • 交易output结构如下:

    根据合约中if-else判定逻辑,下面便是储蓄分红合约的output的构造模型。

    export function controlProgramAction(amount, asset, program){
        return {
            "amount": amount,
            "asset": asset,
            "control_program": program,
            "type": "control_program"
        }
    }
    
    export function controlAddressAction(amount, asset, address){
        return {
            "amount": amount,
            "asset": asset,
            "address": address,
            "type": "control_address"
        }
    }
    
    const output = []
    if(amountDeposited < billAmount){
        output.push(controlProgramAction(amountDeposited, Constant.assetDeposited, Constant.profitProgram))
        output.push(controlAddressAction(amountDeposited, billAsset, saver))
        output.push(controlProgramAction((billAmount-amountDeposited), billAsset, Constant.depositProgram))
    }else{
        output.push(controlProgramAction(amountDeposited, Constant.assetDeposited, Constant.profitProgram))
        output.push(controlAddressAction(billAmount, billAsset, saver))
    }
  • 5)启动前端服务

    编译前端命令如下:

    npm run build

    启动之前需要先启动bufferserver缓冲服务器,然后再启动前端服务,其前端启动命令如下:

    npm start

DAPP缓冲服务器

缓冲服务器主要是为了在管理合约UTXO层面做一些效率方面的处理,包括了对bycoin服务器是如何同步请求的,此外对DAPP的相关交易记录也进行了存储。具体可以参考一下bufferserver源代码

  • 1)储蓄分红合约的架构说明如下:

    • 缓冲服务器构成,目前设计了3张数据表:baseutxobalance表。其中base表用于初始化该DAPP关注的合约program,即在查找utxo集合的时候,仅仅只需过滤出对应的program和资产即可; utxo表是该DAPP合约的utxo集合,其数据是从bycoin服务器中实时同步过来的,主要是为了提高DAPP的并发性; balance表是为了记录用户参与该合约的交易列表。
    • 后端服务由API进程和同步进程组成,其中API服务进程用于管理对外的用户请求,而同步进程包含了两个方面:一个是从bycoin服务器同步utxo,另一个是则是通过区块链浏览器查询交易状态
    • 项目管理员调用update-base接口更新DAPP关注的合约programasset。而utxo同步进程会根据base表的记录来定时扫描并更新本地的utxo表中的信息,并且根据超时时间定期解锁被锁定的utxo
    • 用户在调用储蓄或取现之前需要查询合约的utxo是否可用,可用的utxo集合中包含了未确认的utxo。用户在前端在点击储蓄或取现按键的时候,会调用utxo最优匹配算法选择最佳的utxo,然后调用update-utxo接口对该utxo进行锁定,最后就用户就可以通过插件钱包调用bycoin服务器的构建交易接口来创建交易、签名交易和提交交易。倘若所有合约utxo都被锁定了,则会缩短第一个utxo的锁定时间为60s,设置该时间间隔是为了保证未确认的交易被成功验证并生成未确认的utxo。如果该时间间隔并没有产生新的utxo,则认为前面一个用户并没有产生交易,则60s后可以再次花费该utxo
    • 用户发送交易成功后会生成两条balance记录表,默认状态是失败的,其中交易ID用于向区块链浏览器查询交易状态,如果交易成功则会更新balance的交易状态。此外,前端页面的balance列表表只显示交易成功的记录。
  • 2)编译bufferserver源代码

    按照README安装部署服务需要的软件包MysqlRedis,然后下载源代码并编译:

    make all
编译完成之后,在`target`目录下会生成可执行文件`api`和`updater`。
  • 3)启动服务

    使用root用户创建数据库和数据表,其命令如下:

    mysql -u root -p < database/dump.sql
修改配置文件`config_local.json`,字段说明参考[`README`](https://github.com/oysheng/bufferserver/blob/master/README.md)的`config`配置参数详解。

启动`api`和`updater`服务器,其中`api`是提供`JSON RPC`请求的服务进程,`updater`是提供同步`blockcenter`和区块链浏览器数据请求的服务进程。
./target/api config_local.json

./target/updater config_local.json
相关文章
|
存储 机器学习/深度学习 计算机视觉
稠密矩阵
稠密矩阵是一种特殊形式的矩阵,其中所有元素都是非零的。与稀疏矩阵相比,稠密矩阵在存储和计算时需要更多的空间和计算资源,因为它的所有元素都需要被存储和计算。
521 7
|
SQL 安全 Unix
缓冲区溢出攻击
【8月更文挑战第17天】
625 2
|
9月前
|
自然语言处理 Java 关系型数据库
Java|小数据量场景的模糊搜索体验优化
在小数据量场景下,如何优化模糊搜索体验?本文分享一个简单实用的方案,虽然有点“土”,但效果还不错。
233 0
|
运维 Cloud Native 持续交付
云原生架构的演进与实践####
【10月更文挑战第16天】 云原生,这一概念自提出以来,便以其独特的魅力和无限的可能性,引领着现代软件开发与部署的新浪潮。本文旨在探讨云原生架构的核心理念、关键技术及其在实际项目中的应用实践,揭示其如何帮助企业实现更高效、更灵活、更可靠的IT系统构建与管理。通过深入剖析容器化、微服务、持续集成/持续部署(CI/CD)等核心技术,结合具体案例,本文将展现云原生架构如何赋能企业数字化转型,推动业务创新与发展。 ####
355 47
|
8月前
|
人工智能 搜索推荐 算法
PDF 转 JPG 图片小工具:CodeBuddy 助力解决转换痛点
在 PDF 转 JPG 的实际应用中,用户普遍面临转换质量差、批量处理效率低、格式兼容性不足以及编程实现困难等痛点。而 CodeBuddy 凭借智能代码生成与优化、实时错误诊断修复、助力代码学习拓展,以及支持多场景适配与个性化定制等强大的 AI 编程能力,精准直击这些难题。使用 CodeBuddy 开发 Python PDF 转 JPG 小工具,能够有效提升转换效率与质量,降低开发门槛和成本,为用户带来高效、优质的文件格式转换体验。
303 16
|
8月前
|
监控 搜索推荐 UED
301重定向对SEO的影响:全面解析与最佳实践
本文深入探讨了301重定向在SEO中的作用,涵盖基本概念、积极影响(如保留链接权重、避免重复内容)、潜在风险(如权重传递不完全、错误实施)及最佳实践。同时对比了其他重定向类型,提供了技术实现建议和常见应用场景,帮助网站管理员正确使用301重定向以优化用户体验和搜索引擎表现。
409 16
|
11月前
|
存储 算法 数据处理
Pandas高级数据处理:数据压缩与解压
本文介绍 Pandas 中的数据压缩与解压技术,探讨其在大数据集存储、远程传输和备份归档中的应用场景。Pandas 支持多种压缩格式(如 `.gzip`、`.bz2`、`.zip`),通过 `compression` 参数轻松实现数据的压缩与解压。文中还提供了常见问题的解决方案,如文件扩展名不匹配、内存不足和性能优化,并介绍了自动检测压缩格式和组合压缩加密的高级技巧。掌握这些功能可显著提升数据处理效率。
335 20
|
传感器 存储 安全
智能标签:物品追踪与管理的革新
【10月更文挑战第19天】智能标签技术通过集成RFID、二维码和传感器等技术,实现了物品的高效追踪与管理,广泛应用于物流、零售、医疗、交通和工业等领域,正引领物品管理的革新。本文探讨其原理、技术、应用及未来趋势。
|
监控 开发者 UED
QLineEdit:textChanged、textedited区别
总之,理解 `textChanged`与 `textEdited`之间的细微差别,可以帮助开发者更加精准地控制用户界面的响应逻辑,提升应用程序的互动性和效率。
584 3
|
机器学习/深度学习 算法 数据挖掘
周志华《机器学习》课后习题(第九章):聚类
周志华《机器学习》课后习题(第九章):聚类
1483 0
周志华《机器学习》课后习题(第九章):聚类