2018-04-23 量子链源码部署及智能合约实践

本文是参考《【区块链】DOCKER部署量子链私有网络环境以及部署智能合约实践》和比特币的命令行操作,来通过量子链源码来搭建私有测试网络,并发布智能合约。主要是不习惯docker的操作(命令行太长了),因此就用源代码重来了一次。

1. 源代码编译

参考https://github.com/qtumproject/qtum在ubuntu16上编译源代码,成功后在src目录下生成了qtumd,qtum-cli文件。

2. 启动regtest网络

在src目录下执行:

./qtumd -server -regtest 就可以启动regtest网络

3. 查询当前帐号信息

再启动一个terminal,在src目录下执行:

./qtum-cli -regtest listaccounts

输出:

{

  "": 0.00000000,

}

4. 查询帐号对应的地址

./qtum-cli -regtest getaccountaddress ""

输出:

qXgQefNvuvRVsk2DPuqopqRxEujruTa32T

5. 充值

由于是regtest网络,自己挖矿就有了

需要生成5000个区块(比特币挖100个就有钱了):

./qtum-cli -regtest generate 5000

然后查看账户:

./qtum-cli -regtest getbalance

90000000.00000000

看起来不少

6. 新增一个帐号

./qtum-cli -regtest getnewaddress "elikong"

qVASp4AokEYQ5evDyQF7UBHjKngrR3dr42

下面我们就可以实现目标:

帐号""地址qXgQefNvuvRVsk2DPuqopqRxEujruTa32T

向帐号"elikong"地址qVASp4AokEYQ5evDyQF7UBHjKngrR3dr42

转账100btc

7. 转账

./qtum-cli -regtest sendtoaddress qVASp4AokEYQ5evDyQF7UBHjKngrR3dr42100

8. 挖矿确认

./qtum-cli -regtest generate 1

然后查询数量

./qtum-cli -regtest listaccounts

{

  "": 90019899.99923200,

  "elikong": 100.00000000

}

可以看到elikong帐号有了100btc

9. 查看系统内置的智能合约

./qtum-cli -regtest listcontracts

输出:

{

  "0000000000000000000000000000000000000083": 0.00000000,

  "0000000000000000000000000000000000000082": 0.00000000,

  "0000000000000000000000000000000000000081": 0.00000000,

  "0000000000000000000000000000000000000084": 0.00000000,

  "0000000000000000000000000000000000000080": 0.00000000

}

10. 编写智能合约

打开http://remix.ethereum.org,输入:

pragma solidity ^0.4.0;


contract Greeter        

{

    address creator;    

    string greeting = "hello";    


    function Greeter() public  

    {

        creator = msg.sender;

     //   greeting = _greeting;

    }


    function greet() constant returns (string)         

    {

        return greeting;

    }


    function setGreeting(string _newgreeting)

    {

        greeting = _newgreeting;

    }


     /**********

     Standard kill() function to recover funds

     **********/


    function kill()

    {

        if (msg.sender == creator)

            suicide(creator);  // kills this contract and sends remaining funds back to creator

    }


}

点击右边的detail,bytecode里面复制object的内容:

60806040526040805190810160405280600581526020017f68656c6c6f0000000000000000000000000000000000000000000000000000008152506001908051906020019061004f9291906100a2565b5034801561005c57600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610147565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100e357805160ff1916838001178555610111565b82800160010185558215610111579182015b828111156101105782518255916020019190600101906100f5565b5b50905061011e9190610122565b5090565b61014491905b80821115610140576000816000905550600101610128565b5090565b90565b61038a806101566000396000f300608060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806341c0e1b51461005c578063a413686214610073578063cfae3217146100dc575b600080fd5b34801561006857600080fd5b5061007161016c565b005b34801561007f57600080fd5b506100da600480360381019080803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192905050506101fd565b005b3480156100e857600080fd5b506100f1610217565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610131578082015181840152602081019050610116565b50505050905090810190601f16801561015e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156101fb576000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b565b80600190805190602001906102139291906102b9565b5050565b606060018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156102af5780601f10610284576101008083540402835291602001916102af565b820191906000526020600020905b81548152906001019060200180831161029257829003601f168201915b5050505050905090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106102fa57805160ff1916838001178555610328565b82800160010185558215610328579182015b8281111561032757825182559160200191906001019061030c565b5b5090506103359190610339565b5090565b61035b91905b8082111561035757600081600090555060010161033f565b5090565b905600a165627a7a72305820eb4609861a4d53088ea938f7cc4a477805113f4f31baa67746f137848c4450f90029

11. 发布智能合约

./qtum-cli -regtest createcontract 60806040526040805190810160405280600581526020017f68656c6c6f0000000000000000000000000000000000000000000000000000008152506001908051906020019061004f9291906100a2565b5034801561005c57600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610147565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100e357805160ff1916838001178555610111565b82800160010185558215610111579182015b828111156101105782518255916020019190600101906100f5565b5b50905061011e9190610122565b5090565b61014491905b80821115610140576000816000905550600101610128565b5090565b90565b61038a806101566000396000f300608060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806341c0e1b51461005c578063a413686214610073578063cfae3217146100dc575b600080fd5b34801561006857600080fd5b5061007161016c565b005b34801561007f57600080fd5b506100da600480360381019080803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192905050506101fd565b005b3480156100e857600080fd5b506100f1610217565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610131578082015181840152602081019050610116565b50505050905090810190601f16801561015e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156101fb576000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b565b80600190805190602001906102139291906102b9565b5050565b606060018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156102af5780601f10610284576101008083540402835291602001916102af565b820191906000526020600020905b81548152906001019060200180831161029257829003601f168201915b5050505050905090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106102fa57805160ff1916838001178555610328565b82800160010185558215610328579182015b8281111561032757825182559160200191906001019061030c565b5b5090506103359190610339565b5090565b61035b91905b8082111561035757600081600090555060010161033f565b5090565b905600a165627a7a72305820eb4609861a4d53088ea938f7cc4a477805113f4f31baa67746f137848c4450f90029 2500000 0.00000049 qVASp4AokEYQ5evDyQF7UBHjKngrR3dr42

输出:

{

  "txid": "1cbe4562ede3ddba2e507d3fad73fc47a8d6d098fd47a32cf2feb4032a1cf901",

  "sender": "qVASp4AokEYQ5evDyQF7UBHjKngrR3dr42",

  "hash160": "7f4afe6ab9ab538f7d28f08c2687f7681d1cd0d7",

  "address": "e62b8bc805c33184d9713f7fb1e20606dcfe7a9b"

}

检查智能合约:

./qtum-cli -regtest generate 1

./qtum-cli -regtest listcontracts

输出:

{

  "0000000000000000000000000000000000000082": 0.00000000,

  "0000000000000000000000000000000000000080": 0.00000000,

  "0000000000000000000000000000000000000083": 0.00000000,

  "e62b8bc805c33184d9713f7fb1e20606dcfe7a9b": 0.00000000,

  "0000000000000000000000000000000000000084": 0.00000000,

  "0000000000000000000000000000000000000081": 0.00000000

}

上面红色部分就是刚才发布的合约地址

查询详细:

./qtum-cli -regtest getaccountinfo e62b8bc805c33184d9713f7fb1e20606dcfe7a9b

输出:

{

  "address": "e62b8bc805c33184d9713f7fb1e20606dcfe7a9b",

  "balance": 0,

  "storage": {

    "290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563": {

      "0000000000000000000000000000000000000000000000000000000000000000": "0000000000000000000000007f4afe6ab9ab538f7d28f08c2687f7681d1cd0d7"

    },

    "b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6": {

      "0000000000000000000000000000000000000000000000000000000000000001": "68656c6c6f00000000000000000000000000000000000000000000000000000a"

    }

  },

  "code": "608060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806341c0e1b51461005c578063a413686214610073578063cfae3217146100dc575b600080fd5b34801561006857600080fd5b5061007161016c565b005b34801561007f57600080fd5b506100da600480360381019080803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192905050506101fd565b005b3480156100e857600080fd5b506100f1610217565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610131578082015181840152602081019050610116565b50505050905090810190601f16801561015e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156101fb576000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b565b80600190805190602001906102139291906102b9565b5050565b606060018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156102af5780601f10610284576101008083540402835291602001916102af565b820191906000526020600020905b81548152906001019060200180831161029257829003601f168201915b5050505050905090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106102fa57805160ff1916838001178555610328565b82800160010185558215610328579182015b8281111561032757825182559160200191906001019061030c565b5b5090506103359190610339565b5090565b61035b91905b8082111561035757600081600090555060010161033f565b5090565b905600a165627a7a72305820eb4609861a4d53088ea938f7cc4a477805113f4f31baa67746f137848c4450f90029"

}

12. 运行智能合约

继续回到http://remix.ethereum.org里面的detail,复制FUNCTIONHASHES里面的数据:

{

    "cfae3217": "greet()",

    "41c0e1b5": "kill()",

    "a4136862": "setGreeting(string)"

}

./qtum-cli -regtest callcontract e62b8bc805c33184d9713f7fb1e20606dcfe7a9bcfae3217

输出:

{

  "address": "e62b8bc805c33184d9713f7fb1e20606dcfe7a9b",

  "executionResult": {

    "gasUsed": 22742,

    "excepted": "None",

    "newAddress": "e62b8bc805c33184d9713f7fb1e20606dcfe7a9b",

    "output": "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000568656c6c6f000000000000000000000000000000000000000000000000000000",

    "codeDeposit": 0,

    "gasRefunded": 0,

    "depositSize": 0,

    "gasForDeposit": 0

  },

  "transactionReceipt": {

    "stateRoot": "c0a81c3cac5aa655116ca988620a4f88483244e2e985d4665dc8c04c959dcb2d",

    "gasUsed": 22742,

    "bloom": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",

    "log": [

    ]

  }

}

13. 安装ethabi

由于ethabi在ubuntu上只能通过cargo安装,因此需要先安装cargo

sudo apt install cargo

然后安装ethabi

cargo install ethabi-cli

查看合约输出内容,就是解码上面的output内容

ethabi decode params -t string 0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000568656c6c6f000000000000000000000000000000000000000000000000000000

输出:

string hello

14. 调用setGreeting

这里需要使用ethabi构造输入参数

先从http://remix.ethereum.org里面的detail复制abi,保存为文件greet.json

[

      {

           "constant": false,

           "inputs": [],

           "name": "kill",

           "outputs": [],

           "payable": false,

           "stateMutability": "nonpayable",

           "type": "function"

      },

      {

           "constant": false,

           "inputs": [

                 {

                      "name": "_newgreeting",

                      "type": "string"

                 }

           ],

           "name": "setGreeting",

           "outputs": [],

           "payable": false,

           "stateMutability": "nonpayable",

           "type": "function"

      },

      {

           "constant": true,

           "inputs": [],

           "name": "greet",

           "outputs": [

                 {

                      "name": "",

                      "type": "string"

                 }

           ],

           "payable": false,

           "stateMutability": "view",

           "type": "function"

      },

      {

           "inputs": [],

           "payable": false,

           "stateMutability": "nonpayable",

           "type": "constructor"

      }

]

然后构造参数:

ethabi encode function greet.json setGreeting -p "hello world" --lenient

输出:

a41368620000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000b68656c6c6f20776f726c64000000000000000000000000000000000000000000


这里对比两个命令

l callcontract 链下完成,不会在区块链上产生记录。不消耗gas

l sendtocontract 链上完成,需要同步,会消耗gas

我们使用下面的命令

sendtocontract "contractaddress""data" (amount gaslimit gasprice senderaddress broadcast)

Send funds and data to a contract.


./qtum-cli -regtest sendtocontract e62b8bc805c33184d9713f7fb1e20606dcfe7a9ba41368620000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000b68656c6c6f20776f726c64000000000000000000000000000000000000000000

输出:

{

  "txid": "af73f3f087a351ee672bdcd0d93a61b79a72ebc694bbff489b17089e68401c5c",

  "sender": "qVASp4AokEYQ5evDyQF7UBHjKngrR3dr42",

  "hash160": "7f4afe6ab9ab538f7d28f08c2687f7681d1cd0d7"

}

查询结果:

./qtum-cli -regtest callcontract e62b8bc805c33184d9713f7fb1e20606dcfe7a9bcfae3217

输出:

{

  "address": "e62b8bc805c33184d9713f7fb1e20606dcfe7a9b",

  "executionResult": {

    "gasUsed": 22742,

    "excepted": "None",

    "newAddress": "e62b8bc805c33184d9713f7fb1e20606dcfe7a9b",

    "output": "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000b68656c6c6f20776f726c64000000000000000000000000000000000000000000",

    "codeDeposit": 0,

    "gasRefunded": 0,

    "depositSize": 0,

    "gasForDeposit": 0

  },

  "transactionReceipt": {

    "stateRoot": "6fa927d9a6d5b8794215a5ad465fbd498c051ca3d28046a508fd46aa5f2124ef",

    "gasUsed": 22742,

    "bloom": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",

    "log": [

    ]

  }

}

查询output:

ethabi decode params -t string 0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000b68656c6c6f20776f726c64000000000000000000000000000000000000000000

输出:

string hello world

说明修改成功

(这里没有挖矿,是因为qtum后续自动挖矿了)

15. 合约销毁

就是调用合约的函数kill()

./qtum-cli -regtest sendtocontract e62b8bc805c33184d9713f7fb1e20606dcfe7a9b41c0e1b5

输出:

{

  "txid": "15bd8155a735804946ac5cd24e21a7c414a1806bb9bf6cb65d3431b78628ce84",

  "sender": "qYn9XGorExumdxEdx1TVDXBXLzKYFFMRXN",

  "hash160": "a6f3e9d2c239bab50b60fb5365d1a3e01f861507"

}

查询合约:

./qtum-cli -regtest listcontracts

输出:

{

  "e62b8bc805c33184d9713f7fb1e20606dcfe7a9b": 0.00000000,

  "0000000000000000000000000000000000000083": 0.00000000,

  "0000000000000000000000000000000000000084": 0.00000000,

  "0000000000000000000000000000000000000080": 0.00000000,

  "0000000000000000000000000000000000000082": 0.00000000,

  "0000000000000000000000000000000000000081": 0.00000000

}

实际并没用删除,因为kill函数内部判断了只能创建者删除,因此,我们使用创建者删除:

./qtum-cli -regtest sendtocontract e62b8bc805c33184d9713f7fb1e20606dcfe7a9b41c0e1b5 0 250000 0.00000049qVASp4AokEYQ5evDyQF7UBHjKngrR3dr42

输出:

error code: -3

error message:

Sender address does not have any unspent outputs


提示没有utxo,但是查询账户

./qtum-cli -regtest listaccounts

{

  "": 91959699.69510800,

  "elikong": 198.76914800

}

有资金,为啥没有utxo呢?

./qtum-cli -regtest getaccountaddress "elikong"   

输出:

qY26EDJjSA2S9wjXdLm9JNtosV52eJN6Cg

发现elikong的地址发生了变化,以前是qVASp4AokEYQ5evDyQF7UBHjKngrR3dr42

这个应该就是和比特币不同的地方了,量子链的技术文章里面说实现了虚拟账户层,估计这块就是一个账户对应了多个地址,先不管这个,继续给qVASp4AokEYQ5evDyQF7UBHjKngrR3dr42转账

./qtum-cli -regtest sendtoaddress qVASp4AokEYQ5evDyQF7UBHjKngrR3dr42 100

然后继续执行消耗合约:

./qtum-cli -regtest sendtocontract e62b8bc805c33184d9713f7fb1e20606dcfe7a9b41c0e1b5 0 250000 0.00000049qVASp4AokEYQ5evDyQF7UBHjKngrR3dr42

输出:

{

  "txid": "04ca077bd721063aa0062b7a5d8c3a058181872741e2a88b389fe82dda59ebd1",

  "sender": "qVASp4AokEYQ5evDyQF7UBHjKngrR3dr42",

  "hash160": "7f4afe6ab9ab538f7d28f08c2687f7681d1cd0d7"

}

查询合约:

./qtum-cli -regtest listcontracts

输出:

{

  "0000000000000000000000000000000000000082": 0.00000000,

  "0000000000000000000000000000000000000083": 0.00000000,

  "0000000000000000000000000000000000000084": 0.00000000,

  "0000000000000000000000000000000000000080": 0.00000000,

  "0000000000000000000000000000000000000081": 0.00000000

}

合约确实被删除了

(或者用./qtum-cli -regtest getaccountinfo e62b8bc805c33184d9713f7fb1e20606dcfe7a9b)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,527评论 5 470
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,314评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,535评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,006评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,961评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,220评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,664评论 3 392
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,351评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,481评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,397评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,443评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,123评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,713评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,801评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,010评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,494评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,075评论 2 341

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,566评论 18 139
  • 首先,需要用到UITabBarController的代理 1.在WestriceMainViewControlle...
    Westrice阅读 814评论 0 0
  • 今天的课,老师重点讲如何做笔记,以及如何自学新概念。老师展示了vivian妈妈的笔记,非常值得学习和借鉴。
    漫步和蜗牛阅读 194评论 0 0
  • 太阳用金子 收买着冰雪 枝头垂咽三尺 最先招供 山的两面 一边在鄙弃,一边推崇 河冻封的心在 暗流涌动 雪人的泪 ...
    飘雪衔香阅读 165评论 0 1
  • 妈妈的理发店陪伴我度过了快二十年。 我们家主要的经济来源就是我妈开的一家理发店。 她的理发...
    想变美的猪阅读 687评论 0 0