当前位置: 首页 > news >正文

智能合约笔记

前言:

首先了解下为什么会出现智能合约,打个比方现在有两个人A和B打赌明天会不会下雨,每个人赌注100元,如果第二天下雨则A拿走200元,否则B拿走200元,这样就有一个问题,赌注要到第二天才能见效,如果两个人是知根知底的熟人还是君子,那么可以定一个君子协定,但是这个并不适用于陌生人或者信誉不好的人,那么应该怎么办,只能找个中间人,类似于裁判,需要对赌注结果进行判断而且保管赌金,这就带来了第二个问题,这个中间人可靠不可靠,信任如何解决,这里就出现了智能合约,通过计算机代码来控制合约内容,并保管金额,只要代码经过双方审核没有问题合约生效,就不会有人为因素来干扰,解决了信任问题。

所以智能合约(Smart contracts)是一种基于区块链技术的自动化合约。它们是一组以编程形式定义的计算机代码,旨在执行、验证或执行合同中的特定条件或条款。

智能合约运行在区块链上,通过区块链的去中心化和分布式特性,实现了在没有中间人的情况下进行可靠的交易和合约执行。智能合约的代码和执行结果被记录在区块链的区块中,具有透明性、不可篡改性和可验证性。

智能合约可以用于各种场景,例如数字货币交易、资产转让、投票、供应链管理、保险索赔等。合约的条件和逻辑由编程语言来定义,常见的智能合约平台使用的编程语言包括 Solidity(用于以太坊)、Vyper(用于以太坊)、Corda(用于 Corda 区块链平台)等。

智能合约的执行通常基于预先设定的条件和触发事件。一旦满足了合约的条件,智能合约将自动执行相应的操作,例如转移资金、更新状态或触发其他合约。这种自动化的执行消除了中介机构的需求,减少了交易成本并提高了执行的效率。

搭建以太坊合约:

这里我们以以太坊为例,讲讲底层是如何实现智能合约,首先我们需要知道以以太坊有C和go两个版本,但是其智能合约可以使用如下四种语言:

  1. Solidity ,受JavaScript 启发
  2. Serpent ,受Python启发
  3. Mutan,受Go 启发
  4. LLL 受Lisp 启发

其中Solidity到目前为止是最流行的智能合约编程语言,当然每个不同的区块链会有自己对应的支持的智能合约语言,这里以Solidity进行讲解

首先下载以太坊协议的官方 Go 实现,地址如下:

https://github.com/ethereum/go-ethereum

注意下载版本不要大于v1.12.0,因为该版本的不能再在基于 PoW 的私有链上使用,详情请查看地址:

https://github.com/ethereum/go-ethereum/releases/tag/v1.12.0

下载完成后,可能需要科学上网,搭建好代理端口后执行如下:

export http_proxy=http://127.0.0.1:7890
export https_proxy=http://127.0.0.1:7890

 进入下载的go-ethereum目录执行,如果没有安装go,首先安装go环境:

apt update
apt install golang 
make geth
mv geth /usr/local/bin/geth-1.11.6
geth-1.11.6 version

 

然后安装solidity,首先在如下地址下载对应的二进制文件:

https://github.com/ethereum/solidity/releases

然后执行如下命令讲文件放入bin目录:

mv solc-static-linux /usr/local/bin
solc --version

 

完成后我们就要搭建自己的私有节点,如果我们去公有链除了数据库庞大外执行合约还要花费一定的费用,测试的话就在本地进行测试就好:

首先创建文件genesis.json:,其中部分参数解释如下:

mixhash    与nonce配合用于挖矿,由上一个区块的一部分生成的hash
nonce      nonce就是一个64位随机数,用于挖矿
difficulty 设置当前区块的难度,如果难度过大,cpu挖矿就很难,这里设置较小难度
alloc      用来预置账号以及账号的以太币数量
coinbase   矿工的账号,随便填
timestamp  设置创世块的时间戳
parentHash 上一个区块的hash值,因为是创世块,所以这个值是0
extraData  附加信息,随便填,可以填你的个性信息
gasLimit   该值设置对GAS的消耗总量限制,用来限制区块能包含的交易信息总和
{"config": {"chainId": 111,"homesteadBlock": 0,"eip150Block": 0,"eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000","eip155Block": 0,"eip158Block": 0,"byzantiumBlock": 0,"constantinopleBlock": 0,"petersburgBlock": 0,"istanbulBlock": 0,"ethash": {}},"nonce": "0x0","timestamp": "0x5ddf8f3e","extraData": "0x0000000000000000000000000000000000000000000000000000000000000000","gasLimit": "0x47b760","difficulty": "0x00002","mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000","coinbase": "0x0000000000000000000000000000000000000000","alloc": { },"number": "0x0","gasUsed": "0x0","parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
}

然后执行命令进行节点初始化:

其中参数解释:

init   指定创世块文件的位置,并创建初始块
datadir    设置当前区块链网络数据存放的位置
geth-1.11.6 --datadir data1 init genesis.json

出现如下successfully 证明初始化成功: 

因为我们需要在一台主机上创建多个节点方便操作,,然后执行如下命令,其中--http.addr为本机IP,其中需要注意personal这个namespace高版本已经不用了,如果再想用的话,需要添加
--rpc.enabledeprecatedpersonal这个参数:

geth-1.11.6 --datadir /home/yitai/privatechain/data1 --http --http.api "eth,web3,miner,admin,personal,net" --http.corsdomain "*" --nodiscover --networkid 111 --http.addr 192.168.5.106  --http.port 9049 --port 3366 --allow-insecure-unlock --rpc.enabledeprecatedpersonal

然后会data1文件夹中创建出geth.ipc文件:

然后执行如下命令,此时是

geth-1.11.6 attach ipc:geth.ipc

这里首先我们要Geth JavaScript console熟悉命令,如下地址为官方说明:

https://geth.ethereum.org/docs/interacting-with-geth/javascript-console

Geth JavaScript console 常用对象如下,在console输入前面的对象按tab可以看到对应的方法:

eth:主要包含对区块链进行访问和交互相关的方法
net:包含以下查看p2p网络状态的方法
admin:包含一些与管理节点相关的方法
miner:包含启动&停止挖矿的一些方法
personal:主要包含一些管理账户的方法
txpool:包含一些查看交易内存池的方法
web3:包含了以上对象,还包含一些单位换算的方法

常用方法如下:

创建账户
personal.newAccount()解锁账户
personal.unlockAccount()
解锁账户,指定解锁具体账户
personal.unlockAccount(eth.accounts[0])列出系统中的账户
eth.accounts1、查看账户余额,返回值的单位是 Wei (“ ”里面是自己管理的账户地址)
eth.getBalance()
2、查看账户余额,返回值的单位是 Wei (“ ”里面是自己管理的账户地址)
eth.getBalance("写上账户地址")
3、转换为单位ether,便于阅读
web3.fromWei(eth.getBalance("写上账户地址"),'ether')
4、如果是在里面创建的账户可以调用内部函数拿到地址,不用每次都复制地址。
eth.getBalance(eth.accounts[0])
web3.fromWei(eth.getBalance(eth.accounts[0]),'ether')发起交易(发起方需要是自己管理的账户,其次需要先解锁账户),from:发起交易的地址;to:接受交易的地址
eth.sendTransaction({from:eth.accounts[0],to:"接受交易的地址",value:100000})列出当前区块高度
eth.blockNumber获取交易信息
eth.getTransaction()获取区块信息
eth.getBlock()开始挖矿
miner.start()
表示一直挖矿
miner.start(1)
查看
eth.coinbase
停止挖矿
miner.stop()
开始挖矿,当挖到一个块时就停止,
miner.start(1);admin.sleepBlocks(1);miner.stop()Wei 换算成以太币
web3.fromWei()以太币换算成 Wei
web3.toWei()交易油中的状态
bxpool.status

查看我们创建的节点:

查看当前连接节点为0: 

然后我们在Geth JavaScript console下添加两个新账号:

 

可以看到创建了如下两个账号:

0x20cabfdcc5db00741f71a889085d39ae4c9bd990
0x6e466264f57e3d618284b3162409883599ebf138

下面我们设置其中一个为Coinbase ,挖到一个区块会奖励5个以太币,挖矿所得的奖励会进入矿工的账户,这个账户叫做coinbase,默认情况下coinbase是本地账户中的第一个账户,通过miner.setEtherbase()可将其他账户设置成coinbase。Coinbase 地址指的是在以太坊网络上进行挖矿活动时,挖矿奖励被发送到的地址。这个地址通常是挖矿节点的钱包地址,并且此时查看余额为0:

下面就开始挖矿,由于我们的是私有链,而且难度系数低,所以很容易就挖到:

需要注意getBalance()返回值的单位是wei,wei是以太币的最小单位,1个以太币=10的18次方个wei。要查看有多少个以太币,可以用web3.fromWei()将返回值换算成以太币:

这个时候我们看看当前区块总数为17,并且在miner中可以看到对应的账号地址:

下面我们尝试进行一次转账,讲第一个账户的钱转一部分到第二个账户,转移前需要进行解锁账户:

解锁完成后进行转账操作,可以看到转账成功后会有一个账单地址,追踪这个地址可以看到交易的详细信息:

转账虽然成功,但是这个时候查看该地址余额还是显示为0:

 

这是因为虽然此时交易已经提交到区块链,返回了交易的hash,但还未被处理,这可以通过查看txpool来验证:

其中有一条pending的交易,pending表示已提交但还未被处理的交易,要使交易被处理,必须要挖矿。这里我们启动挖矿,然后等待挖到一个区块之后就停止挖矿,执行后可以看到已经成功转账,至于为什么,这个要说以太坊的Proof-of-Work工作量机制,不过后续以太坊使用Proof-of-Stake(PoS)是一种区块链共识机制,与传统的Proof-of-Work(PoW)机制不同。在PoS中,区块链的验证和记账权不是通过解决复杂的数学难题来获得,而是基于参与者在系统中持有的加密货币(通常是同一区块链的本地代币)的数量。

此时我们再查刚才的转账记录地址,可以看到其被记录到了18区块,查看对应的18区块可以看到对应的交易账单: 

下面我们开始自己编写一个合约,具体的Solidity语法请参考如下地址,我们的测试代码也取自官方案例:

https://docs.soliditylang.org/zh/v0.8.17/introduction-to-smart-contracts.html

测试代码如下,其主要功能是mint,send两个方法,mint方法是向指定的地址发送代币, send为从调用者处发送代币到指定地址:

// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.4;contract Coin {// 关键字 "public" 使变量可以从其他合约中访问。address public minter;mapping (address => uint) public balances;// 事件允许客户端对您声明的特定合约变化做出反应event Sent(address from, address to, uint amount);// 构造函数代码只有在合约创建时运行constructor() {minter = msg.sender;}// 向一个地址发送一定数量的新创建的代币// 但只能由合约创建者调用function mint(address receiver, uint amount) public {require(msg.sender == minter);balances[receiver] += amount;}// 错误类型变量允许您提供关于操作失败原因的信息。// 它们会返回给函数的调用者。error InsufficientBalance(uint requested, uint available);// 从任何调用者那里发送一定数量的代币到一个地址function send(address receiver, uint amount) public {if (amount > balances[msg.sender])revert InsufficientBalance({requested: amount,available: balances[msg.sender]});balances[msg.sender] -= amount;balances[receiver] += amount;emit Sent(msg.sender, receiver, amount);}
}

我们可以通过如下地址进行在线测试:

https://remix.ethereum.org/#lang=en&optimize=false&runs=200&evmVersion=null

首先我们新建一个文件后讲上述代码粘贴到新建文本中,然后点击编译:

首先需要部署合约,选择好地址点击部署就可以看到部署的合约:

首先选择要接收的地址,然后设置好金额,执行后可以看到debug中有参数数据,这样就会执行mint中的代码,向指定的地址转入50代币,然后查询可以看到成功转入50代币: 

然后执行第二个转账send方法, 执行这个方法会将调用者的代币转入指定地址中,可以看到调用地址的金额减少了20,被转入了指定的地址:

下面我们把合约部署再我们自己的私链中,首先查看编译详情,其中有ABI和字节码数据:

然后进入如下网址对ABI的json数据进行转移:

https://www.bejson.com/

ABI转义前数据如下:

[{"inputs": [],"stateMutability": "nonpayable","type": "constructor"},{"inputs": [{"internalType": "uint256","name": "requested","type": "uint256"},{"internalType": "uint256","name": "available","type": "uint256"}],"name": "InsufficientBalance","type": "error"},{"anonymous": false,"inputs": [{"indexed": false,"internalType": "address","name": "from","type": "address"},{"indexed": false,"internalType": "address","name": "to","type": "address"},{"indexed": false,"internalType": "uint256","name": "amount","type": "uint256"}],"name": "Sent","type": "event"},{"inputs": [{"internalType": "address","name": "","type": "address"}],"name": "balances","outputs": [{"internalType": "uint256","name": "","type": "uint256"}],"stateMutability": "view","type": "function"},{"inputs": [{"internalType": "address","name": "receiver","type": "address"},{"internalType": "uint256","name": "amount","type": "uint256"}],"name": "mint","outputs": [],"stateMutability": "nonpayable","type": "function"},{"inputs": [],"name": "minter","outputs": [{"internalType": "address","name": "","type": "address"}],"stateMutability": "view","type": "function"},{"inputs": [{"internalType": "address","name": "receiver","type": "address"},{"internalType": "uint256","name": "amount","type": "uint256"}],"name": "send","outputs": [],"stateMutability": "nonpayable","type": "function"}
]

然后执行如下命令,将json字符串转义成字符串,并在geth控制台中将其赋值给新变量:

abi = JSON.parse('[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Sent\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"balances\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"minter\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"send\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]')
myContract = web3.eth.contract(abi)

 

下面执行如下命令,预估手续费:

bytecode = "0x608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506105fc806100606000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c8063075461721461005157806327e235e31461006f57806340c10f191461009f578063d0679d34146100bb575b600080fd5b6100596100d7565b60405161006691906103b6565b60405180910390f35b61008960048036038101906100849190610402565b6100fb565b6040516100969190610448565b60405180910390f35b6100b960048036038101906100b4919061048f565b610113565b005b6100d560048036038101906100d0919061048f565b6101c5565b005b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016020528060005260406000206000915090505481565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461016b57600080fd5b80600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546101ba91906104fe565b925050819055505050565b600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205481111561028a5780600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546040517fcf479181000000000000000000000000000000000000000000000000000000008152600401610281929190610532565b60405180910390fd5b80600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546102d9919061055b565b9250508190555080600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461032f91906104fe565b925050819055507f3990db2d31862302a685e8086b5755072a6e2b5b780af1ee81ece35ee3cd33453383836040516103699392919061058f565b60405180910390a15050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006103a082610375565b9050919050565b6103b081610395565b82525050565b60006020820190506103cb60008301846103a7565b92915050565b600080fd5b6103df81610395565b81146103ea57600080fd5b50565b6000813590506103fc816103d6565b92915050565b600060208284031215610418576104176103d1565b5b6000610426848285016103ed565b91505092915050565b6000819050919050565b6104428161042f565b82525050565b600060208201905061045d6000830184610439565b92915050565b61046c8161042f565b811461047757600080fd5b50565b60008135905061048981610463565b92915050565b600080604083850312156104a6576104a56103d1565b5b60006104b4858286016103ed565b92505060206104c58582860161047a565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006105098261042f565b91506105148361042f565b925082820190508082111561052c5761052b6104cf565b5b92915050565b60006040820190506105476000830185610439565b6105546020830184610439565b9392505050565b60006105668261042f565b91506105718361042f565b9250828203905081811115610589576105886104cf565b5b92915050565b60006060820190506105a460008301866103a7565b6105b160208301856103a7565b6105be6040830184610439565b94935050505056fea2646970667358221220b7068a932ac927292afefef1993fb5fbdd8d9f62b10b9c5559a47313126c03b964736f6c63430008110033"
web3.eth.estimateGas({data: bytecode})

 其中需要注意字节码前面要加上0x,并且要注意编译版本,如果过高会报错:

下面解锁账户:

personal.unlockAccount(eth.coinbase)

 

开始部署合约:

contractInstance =myContract.new({from:"0x20cabfdcc5db00741f71a889085d39ae4c9bd990",data:bytecode,gas:1000000})

执行看到如下为成功:

输入contractInstance检查合约是否正确:

这里需要注意address为未定义是因为合约还没有被放到链上,所以我们需要挖一下矿把合约写入链上:

miner.start(1);admin.sleepBlocks(1);miner.stop();

写入成功后可以看到具体的合约方法和地址: 

 下面我们先查询下新创建账号0xdd2b86ed99b469fe81063257f65b07b45047f73c的金额,调用call类型函数的方法:

contractInstance.balances.call("0xdd2b86ed99b469fe81063257f65b07b45047f73c",{from:"0x20cabfdcc5db00741f71a889085d39ae4c9bd990"})

下面我们尝试执行mint向指定地址添加金额,其中需要注意写入区块的因为是POW共识,所以一定要挖矿:

contractInstance.mint("0xdd2b86ed99b469fe81063257f65b07b45047f73c","10",{from:"0x20cabfdcc5db00741f71a889085d39ae4c9bd990"})

下面我们尝试转账,将地址 0x20cabfdcc5db00741f71a889085d39ae4c9bd990的转到0xdd2b86ed99b469fe81063257f65b07b45047f73c:

contractInstance.send("0xdd2b86ed99b469fe81063257f65b07b45047f73c","11",{from:"0x20cabfdcc5db00741f71a889085d39ae4c9bd990"})

并且通过交易hash可以查看交易信息:

eth.getTransactionReceipt("0x77538ee9b7b75c4235f81786be6ddd08f1087e91129defabbe417dbfb8e5d66c")

以上就一个创建私链并且添加自己的智能合约过程

区别:

这里有人可能就有疑问了,比特链是不是和以太链一样可以创建自己的智能合约,但是很遗憾,比特币作为第一个区块链和加密货币,并没有原生支持智能合约功能。比特币的设计目标主要是作为一种去中心化的数字货币,用于安全地进行价值转移。然而,虽然比特币本身不支持智能合约,但有一些项目和层次协议试图在比特币上实现智能合约功能。但是都是通过构建在比特币之上的侧链或层次协议来实现智能合约功能,并不是比特币本身的原生功能。相比之下,以太坊是专门设计用于支持智能合约的区块链平台,具有原生的智能合约功能,并提供了丰富的开发工具和编程语言来编写和部署智能合约。

比特币链(Bitcoin blockchain)和以太坊链(Ethereum blockchain)是两个不同的区块链网络,它们在设计目标、功能和特点上有一些显著的区别。

  1. 设计目标:

    • 比特币链:比特币链的主要设计目标是实现去中心化的数字货币系统,即比特币(BTC)。它旨在提供安全、可靠的价值转移和存储,使用户可以进行去中心化的交易,而不依赖于中心化的机构。
    • 以太坊链:以太坊链的设计目标是提供一个通用的区块链平台,支持智能合约和去中心化应用(DApps)的创建和执行。以太坊旨在实现一个可编程的区块链,使开发人员能够构建和部署各种去中心化应用和智能合约。
  2. 智能合约功能:

    • 比特币链:比特币链本身没有原生支持智能合约功能。虽然比特币脚本语言(Script)提供了一些简单的脚本操作,如多重签名和时间锁定,但它的功能相对有限。
    • 以太坊链:以太坊链是一个专为智能合约而设计的平台。它提供了一个完整的智能合约执行环境,使用 Solidity 等编程语言编写智能合约。以太坊的智能合约能够运行复杂的逻辑、与其他合约进行交互,并支持创建去中心化应用程序(DApps)和发行自定义代币。
  3. 编程语言和开发生态系统:

    • 比特币链:比特币链的脚本语言相对简单,不太适合复杂的应用程序开发。因此,比特币上的开发生态系统相对较小,主要集中在与比特币交易和钱包相关的工具和库上。
    • 以太坊链:以太坊提供了更丰富的编程语言和开发工具,主要使用 Solidity 进行智能合约开发。以太坊拥有庞大的开发者社区和丰富的开发生态系统,涵盖了各种开发框架、库和工具,以支持以太坊智能合约和DApps的开发。
  4. 扩展性和性能:

    • 比特币链:比特币链的设计注重安全性和去中心化,因此其扩展性相对较低。比特币链的区块确认时间较长(约10分钟),交易吞吐量有限。
    • 以太坊链:以太坊链在追求扩展性方面做出了一些努力,但仍面临着性能和可扩展性挑战。以太坊的区块确认时间较短(约15秒),但随着交易增加,网络拥堵和交易费用也可能增加。

总结起来,比特币链和以太坊链是两个不同的区块链网络,各自有不同的设计目标和功能。比特币链专注于去中心化的数字货币交易,而以太坊链则提供了更丰富的智能合约平台和去中心化应用开发能力。所以目前有很多基于以太坊创建的智能合约,但是比特币只能采用其他方法来创建智能合约,具体的方法后续会进行讲解。

永续合约:

在币圈经常会听到永续合约,很多新手对这个概念可能比较模糊,这里对永续合约进行讲解,要理解永续合约首先要理解什么叫期货,永续合约的全称为永续期货合约。

首先了解下什么是期货,正常我们购买东西都是一手交钱一手交货,这个就是现货交易,那么期货交易就是双方约定好在将来某个时间以某个价格交易某商品,约定的这个合约就是期货合约,比如我们和经销商约定好六个月后以十元一斤价格购买一百斤土豆,等到半年后的这天交割日经销商必须按照十元一斤给我一百斤土豆,而我也要支付响应的价格,这个就是期货交割合约,在这半年中如何保证双方不会违约,这就双方要交的保证金到对应的监管方,如果半年后土豆价格暴涨,我们就赚了,反之就要承担响应的损失。

理解了什么是期货合约,我们就知道合约就是双方进行一个约定,到约定日期生效就是我们的期货合约,但是如果我们不约定时间,或者说不受时间限制双方约定的就属于永续合约,双方均可以随时进行平仓结束合约或开始合约,这就是永续合约。

永续合约是一种衍生品合约,其特点如下:

  1. 无到期日:与传统期货合约不同,永续合约没有固定的到期日。交易者可以持有合约的头寸,直到决定平仓或被强制平仓。

  2. 资金费率机制:为了保持永续合约价格与标的资产价格的接近程度,永续合约引入了资金费率机制。资金费率是交易者之间的利息交换。如果合约价格与标的资产价格之间存在差异,资金费率将根据差异情况进行调整,以鼓励合约价格向标的资产价格靠近。

  3. 杠杆交易:永续合约通常支持杠杆交易,允许交易者使用较少的自有资金来控制更大数量的标的资产。交易者可以通过选择适当的杠杆倍数来放大头寸规模,以增加潜在盈利机会。然而,杠杆交易也带来了增加的风险,可能导致损失扩大。

  4. 强平机制:由于没有到期日,永续合约引入了强平机制,以防止交易者因持有不可持续的头寸而遭受巨大损失。交易所会设定一定的保证金要求,并根据市场价格波动情况对持仓进行标记和强制平仓。

简单说当我们购买永续合约的时候会根据当前行情对未来进行一个判断,比如我预计以后BTC价格会下降,那么我只要买看空的永续合约,当然也可以加杠杆进行操作,这样如果后续BTC真的和我预计的一样下跌,那么和我购买时候的价格相比,跌的金额乘杠杆就是我们的盈利,但是如果预测错了,价格上涨,则涨的价格就是我们损失的,如果杠杆加的太高,可能会因为保证金不足被强行平仓。

永续合约分为两种正向合约和反向合约,正向合约一张合约面值按BTC数量(价值多少个BTC),而反向合约是按USDT数量(价值多少USDT),下面我们用两个合约进行解释:

合约类型合约面值
一张正向BTC合约面值0.1 BTC
一张反向BTC合约面值        100 USDT

正向合约:

​正向合约,即稳定币合约,指用USDT或者法币对比特币做合约交易。目前国内一些永续合约交易所已经开放多币种交易,也就是说你只要持有足够USDT,就可以直接做多个主流币种的合约交易。比如我们交易的是BTC,以USDT计价,保证金也是USDT。

假设当前BTC价格为2W美金,我们想以两倍杠杆买入5张BTC正向合约,那么我们需要支出多少保证金,并且可以操作的仓位价值又是多少,下面进行计算:

正向合约仓位价格=合约面值*合约张数*当前价格正向合约仓位价格=杠杆倍数*保证金

所以很好理解:

合约面值*合约张数*当前价格=杠杆倍数*保证金

也就是说:

保证金=(合约面值*合约张数*当前价格)/杠杆倍数

套用金额分析:

(0.1*5*2W)/2=5000USDT

所以我们需要支付5000USDT来控制10000USDT的仓位价格,也就是5张价值0.1BTC价值10000USDT的合约。

然后算下我们的盈利,这里以看涨为例,看空则相反:

盈利=(平仓价-开仓价)*合约面值*合约张数

也就是说如果我买的时候是2w美金,现在我想平仓了,当前价格是3w美金,则结果如下:

(30000-20000)*0.1*5=5000usdt

就是我用5000usdt使用两倍杠杆正向合约赚了5000usdt

那什么情况下会爆仓,当亏损=保证金的情况下就会亏损,对应的公式可以计算

差价*合约面值*合约张数=保证金
保证金=(合约面值*合约张数*当前价格)/杠杆倍数
差价*合约面值*合约张数=(合约面值*合约张数*开仓价)/杠杆倍数

最后公式为:

差价 = 开仓价/杠杆倍数

则如果是2w美金,如果是两倍杠杆,则当20000/2=10000,跌幅为1w的情况下会被强行平仓,如果是十倍杠杆,则20000/10=2000,当跌了2000就被平仓,也就是当BTC跌幅为10%,就被强行平仓。

反向合约:

下面来看看反向合约,反向合约是指持有多个币种做对应交易,即币本位合约。反向合约意味着,如果你要做比特币的合约交易,就必须用比特币作为本位币,如果是以太坊合约交易,那就得持有以太坊才行。

假设在反向合约中我们想拥有和上面一样10000USDT的仓位,当前一张反向合约对应100usdt,那么我们需要购买100张合约,算下对应的保证金

反向合约的仓位价值=合约面值*合约张数 
反向合约的仓位价值=杠杆倍数*保证金数量*当前价格

所以可以得到如下公式:

合约面值*合约张数=杠杆倍数*保证金数量*当前价格

所以对应的保证金数量为:

保证金数量=(合约面值*合约张数)/(杠杆倍数*当前价格)

对应的我们计算(100*100)/(2*20000)=0.25BTC,计算下0.25BTC,0.25*20000=50000usdt,可以发现和正向合约的价格是一样的,但是我们使用的保证金不是ustd而是对应的本币btc

然后我们同样计算盈利:

反向合约的盈亏 = 合约乘数*合约张数/开仓价-合约乘数*合约张数/平仓价=(1/开仓价-1/平仓价)*合约乘数*合约张数

如果买的时候是2w美金。卖的时候是3w美金,计算盈利为100*100/20000-100*100/30000=0.1666..btc,按照当前的价格3w计算约等于5000usdt,和正向相同,但是由于我们是反向合约,交易的是btc,做多的时候随着价格升值,我们获得的btc数量是变少的,做少的时候由于价格降低,我们获得的btc是变多的,这个很好理解,因为我们最后还是要将btc对应到usdt价格。

再来看看爆仓,分为做多和做空:

平仓价 = 开仓价(1-1/(杠杆倍数+1)) 做多 
平仓价 = 开仓价(1+1/(杠杆倍数-1)) 做空 

可以发现如果是做多,当为一倍杠杆的情况下,2w的开仓价,当跌了50%,即1w美金就会爆仓,但是做空的情况下一倍杠杆不会爆仓,因此反向合约做空比做多安全,BitMEX也被称为空军基地。

总结:

上面对智能合约技术层面进行了分析,并讲解了永续合约,智能合约在加密货币市场玩的比较多,永续合约也被很多投资客追捧,但是投资需谨慎,币圈价格震荡太大,还是要做好基础知识的研究再入场,不要脑子一热就冲进去,不要被暴富神话冲昏了头脑。

 

 

相关文章:

智能合约笔记

前言: 首先了解下为什么会出现智能合约,打个比方现在有两个人A和B打赌明天会不会下雨,每个人赌注100元,如果第二天下雨则A拿走200元,否则B拿走200元,这样就有一个问题,赌注要到第二天才能见效&…...

脱离于ASP.NET 和Visual Studio编辑Razor脚本

Razor Pad是一个编辑Razor脚本的工具,脱离于ASP.NET 和Visual Studio。 github地址:GitHub - RazorPad/RazorPad: RazorPad is a quick and simple stand-alone editing environment that allows anyone (even non-developers) to author Razor templat…...

MetaGPT前期准备与快速上手

大家好,MetaGPT 是基于大型语言模型(LLMs)的多智能体协作框架,GitHub star数量已经达到31.3k。 接下来我们聊一下快速上手 这里写目录标题 一、环境搭建1.python 环境2. MetaGpt 下载 二、MetaGPT配置1.调用 ChatGPT API 服务2.简…...

Java、C#、Python间的Battle

一、编译原理和开发效率 编译速度: C# (约大于等于) JAVA > Python python的编译原理 前提:python 3.6 python不会直接编译源码 而是把源码直接扔给解释器,这种方式 使得python非常灵活,让它的开发效…...

【图形学】探秘图形学奥秘:DDA与Bresenham算法的解密与实战

​🌈个人主页:Sarapines Programmer🔥 系列专栏:《图形学 | 图像解码》⏰诗赋清音:云生高巅梦远游, 星光点缀碧海愁。 山川深邃情难晤, 剑气凌云志自修。 ​ 目录 🌌1. 初识模式识别…...

微服务-Gateway

案例搭建 官网地址 父Pom <com.alibaba.cloud.version>2.2.8.RELEASE</com.alibaba.cloud.version> <com.cloud.version>Hoxton.SR12</com.cloud.version> <com.dubbo.version>2.2.7.RELEASE</com.dubbo.version> <dependencyManagem…...

【用队列实现栈】【用栈实现队列】Leetcode 232 225

【用队列实现栈】【用栈实现队列】Leetcode 232 225 队列的相关操作栈的相关操作用队列实现栈用栈实现队列 ---------------&#x1f388;&#x1f388;题目链接 用队列实现栈&#x1f388;&#x1f388;------------------- ---------------&#x1f388;&#x1f388;题目链…...

Angular系列教程之观察者模式和RxJS

文章目录 引言RxJS简介RxJS中的设计模式观察者模式迭代器模式 示例代码RxJS 在 Angular 中的应用总结 引言 在Angular开发中&#xff0c;我们经常需要处理异步操作&#xff0c;例如从后端获取数据或与用户的交互。为了更好地管理这些异步操作&#xff0c;Angular中引入了RxJS&…...

展厅设计中搭建的小常识

1、展厅的安全问题 展厅的空间面积大&#xff0c;平时为出现公开展览时人员较少&#xff0c;但遇到开展活动、会展展览时人流量将大大增多&#xff0c;无论是临时的展厅展示还是长期的展示安全问题即使不说都应该是装饰的重中之重&#xff0c;所以在从前期设计规划到后期施工采…...

LeetCode 98. 验证二叉搜索树

98. 验证二叉搜索树 给你一个二叉树的根节点 root &#xff0c;判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义如下&#xff1a; 节点的左子树只包含 小于 当前节点的数。节点的右子树只包含 大于 当前节点的数。所有左子树和右子树自身必须也是二叉搜索树。 示例…...

自定义shell工具函数之pull_image()

这是一个名为pull_image的Shell脚本函数。让我来解释一下这个函数的功能&#xff1a; function pull_image() {image$1DOCKER_IMAGE_MIRROR$(get_config_or_env DOCKER_IMAGE_MIRROR)if [[ "${DOCKER_IMAGE_MIRROR}" "1" ]]; thenif [[ "$(uname -m…...

2019年认证杯SPSSPRO杯数学建模C题(第二阶段)保险业的数字化变革全过程文档及程序

2019年认证杯SPSSPRO杯数学建模 基于统计建模的车险业数字变革研究 C题 保险业的数字化变革 原题再现&#xff1a; 车险&#xff0c;即机动车辆保险。保险自身是一种分散风险、消化损失的经济补偿制度&#xff0c;车险即为分散机动车辆在行驶过程中可能发作的未知风险和损失…...

【数据结构和算法】反转链表

其他系列文章导航 Java基础合集数据结构与算法合集 设计模式合集 多线程合集 分布式合集 ES合集 文章目录 其他系列文章导航 文章目录 前言 一、题目描述 二、题解 2.1 方法一&#xff1a;迭代&#xff08;双指针&#xff09; 2.2 方法二&#xff1a;递归 三、代码 3.…...

What is `GenericFilterBean` does?

GenericFilterBean 是 SpringWeb 框架中提供的一个抽象基类&#xff0c;其对 javax.servlet.Filter接口进行了封装和扩展&#xff0c;它简化了在 Servlet环境下创建自定义过滤器的工作。 GenericFilterBean 主要特点包括&#xff1a; 集成 Spring 容器&#xff1a; 由于它是一…...

突破通胀风险,聚焦现货黄金投资机遇

随着全球经济不断发展和金融市场的波动&#xff0c;通胀风险成为各界关注的焦点。在面对通胀带来的财务压力和资产贬值的威胁时&#xff0c;投资者都在寻找稳定且可靠的避险资产。而现货黄金作为一种值得瞩目的投资工具&#xff0c;正吸引着越来越多投资者的目光。 黄金作为一种…...

Jenkins集成Sonar Qube

下载插件 重启Jenkins 容器 sonarqube 使用令牌 Jenkins 配置 重新构建...

Angular系列教程之zone.js和NgZone

文章目录 什么是zone.jsZone的工作原理Zone的常见用途NgZone&#xff1a;Angular中的zone.js使用NgZone使用NgZone执行代码使用NgZone外部检测 结论 什么是zone.js 在Angular中&#xff0c;zone.js是一个非常重要的库&#xff0c;它为我们提供了一种跟踪和管理异步操作的机制。…...

阿里巴巴的第二代通义千问可能即将发布:Qwen2相关信息已经提交HuggingFace官方的transformers库

本文来自DataLearnerAI官方网站&#xff1a;阿里巴巴的第二代通义千问可能即将发布&#xff1a;Qwen2相关信息已经提交HuggingFace官方的transformers库 | 数据学习者官方网站(Datalearner) 通义千问是阿里巴巴开源的一系列大语言模型。Qwen系列大模型最高参数量720亿&#xf…...

肯尼斯·里科《C和指针》第6章 指针(6)编程的练习:查找字符

1.编写一个函数&#xff0c;它在一个字符串中进行搜索&#xff0c;查找在一个给定字符集合中出现的所有字符。这个函数的原型如下&#xff1a; char *find_char( char const *source, char const *chars ); 它的基本想法是查找source字符串中匹配chars字符串中任何字符的第1个…...

Entity Framework知识点整理

Entity Framework Entity Framework&#xff08;EF&#xff09;是微软提供的一种对象关系映射&#xff08;Object-Relational Mapping&#xff0c;ORM&#xff09;框架&#xff0c;用于在.NET应用程序和关系型数据库之间建立映射关系。它简化了数据访问层的开发&#xff0c;使…...

Python:操作 Excel 折叠

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

GitHub 趋势日报 (2025年06月08日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...

laravel8+vue3.0+element-plus搭建方法

创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...

Linux 内存管理实战精讲:核心原理与面试常考点全解析

Linux 内存管理实战精讲&#xff1a;核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用&#xff0c;还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别

【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而&#xff0c;传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案&#xff0c;能够实现大范围覆盖并远程采集数据。尽管具备这些优势&#xf…...

宇树科技,改名了!

提到国内具身智能和机器人领域的代表企业&#xff0c;那宇树科技&#xff08;Unitree&#xff09;必须名列其榜。 最近&#xff0c;宇树科技的一项新变动消息在业界引发了不少关注和讨论&#xff0c;即&#xff1a; 宇树向其合作伙伴发布了一封公司名称变更函称&#xff0c;因…...

【p2p、分布式,区块链笔记 MESH】Bluetooth蓝牙通信 BLE Mesh协议的拓扑结构 定向转发机制

目录 节点的功能承载层&#xff08;GATT/Adv&#xff09;局限性&#xff1a; 拓扑关系定向转发机制定向转发意义 CG 节点的功能 节点的功能由节点支持的特性和功能决定。所有节点都能够发送和接收网格消息。节点还可以选择支持一个或多个附加功能&#xff0c;如 Configuration …...

高考志愿填报管理系统---开发介绍

高考志愿填报管理系统是一款专为教育机构、学校和教师设计的学生信息管理和志愿填报辅助平台。系统基于Django框架开发&#xff0c;采用现代化的Web技术&#xff0c;为教育工作者提供高效、安全、便捷的学生管理解决方案。 ## &#x1f4cb; 系统概述 ### &#x1f3af; 系统定…...

【WebSocket】SpringBoot项目中使用WebSocket

1. 导入坐标 如果springboot父工程没有加入websocket的起步依赖&#xff0c;添加它的坐标的时候需要带上版本号。 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId> </dep…...

鸿蒙HarmonyOS 5军旗小游戏实现指南

1. 项目概述 本军旗小游戏基于鸿蒙HarmonyOS 5开发&#xff0c;采用DevEco Studio实现&#xff0c;包含完整的游戏逻辑和UI界面。 2. 项目结构 /src/main/java/com/example/militarychess/├── MainAbilitySlice.java // 主界面├── GameView.java // 游戏核…...