Friend.Tech是一个部署在Base链上的SocialFi平台,为用户提供了一个独特的交互平台,能够在去中心化环境中实现社交影响力的货币化。
Friend.Tech是一个新兴的区块链社交平台,在短时间内引起了广泛关注;该平台的注册需要绑定X(twitter) 账户,每个账户都有其「社交价值」,可以购买自己和别人的账户股权,当你持有别人账户的股权时,就可以和此账户聊天。
\ 本文仅从技术层面分析下 friend.tech 项目,不构成任何投资建议。
\ friend.tech是Base链上的的SocialFi项目,在Base浏览器上可以找到项目的合约代码:
合约名称:FriendtechSharesV1
合约地址:0xCF205808Ed36593aa40a44F10c7f7C2F67d4A4d4
address public protocolFeeDestination; // 协议收费地址
uint256 public protocolFeePercent; // 协议收费比率
uint256 public subjectFeePercent; // 股权持有者收费比率
每次买入卖出一个账户的股权(key),账户和项目方都要收手续费,目前根据链上数据可知手续费都是5% 。
event Trade(address trader, address subject, bool isBuy, uint256 shareAmount, uint256 ethAmount, uint256 protocolEthAmount, uint256 subjectEthAmount, uint256 supply);
每次买卖行为都会触发交易事件,交易事件记录了买方和卖方的地址,买入key的数量和使用的eth数量,以及收取的手续费和交易后key的供应量。 可以在区块中监听此事件来进行链上数据分析。
function getPrice(uint256 supply, uint256 amount) public pure returns (uint256) {
uint256 sum1 = supply == 0 ? 0 : (supply - 1 )* (supply) * (2 * (supply - 1) + 1) / 6;
uint256 sum2 = supply == 0 && amount == 1 ? 0 : (supply - 1 + amount) * (supply + amount) * (2 * (supply - 1 + amount) + 1) / 6;
uint256 summation = sum2 - sum1;
return summation * 1 ether / 16000;
}
其中supply表示key的供应量,amount表示要交易的key数量。可以从公式中看到当买key的第一个份额是免费的(合约要求key的拥有账户才能买第一个份额)。
\ 对于sum1和sum2的计算用到了前n个数的平方和公式: 推导见这里。
$$ sum=\frac{n \cdot (n + 1) \cdot (2n + 1)}{6} $$
对于价格的计算:
$$ price=\frac{\text{summation}}{16000} \times 1 \, \text{ether} $$
假设amount为1,则summation=sum2-sum1=n^2:
$$ price=\frac{n^2}{16000} \times 1 \, \text{ether} $$
后面乘 1ether 是使用因子使结果转换为wei,可以简化为:
$$ price=\frac{n^2}{16000} $$
\ 这就是项目的经济模型,即 Price in ETH = supply^ 2 / 16000。在 friend.tech的交互中也验证了这一点。
<div align="center">
</div>
每组key的价格都会随着持有人的增加而呈现“指数增长”,所以当key被购买或者出售时,key的价格都会产生波动。price = supply^2 是一个指数函数,而16000只是为了使价格增长平缓一点,从而更符合市场的匹配关系。
<div align="center">
数据来源:https://onedrive.live.com/view.aspx?resid=C078415A103A3F40%211094&authkey=!ANE0-sqb5hAftiI </div>
\ 随着发行股份总量的不断增长,买卖股份之间的价差净值会越来越大,但价差率(价差/卖价)会越来越小。价差存在的原因并不复杂,股份的增长是从 0 开始,因而必然是先有买后有卖,卖方总是要落后于买方的。在如下函数中体现:
function getBuyPrice(address sharesSubject, uint256 amount) public view returns (uint256) {
return getPrice(sharesSupply[sharesSubject], amount);
}
function getSellPrice(address sharesSubject, uint256 amount) public view returns (uint256) {
return getPrice(sharesSupply[sharesSubject] - amount, amount);
}
可以看出买key时候的supply是当前key的供应量,而卖key时的supply=当前的供应量-卖出的数量;
\ 不同供应量对应的价格关系: <div align="center">
数据来源:https://onedrive.live.com/view.aspx?resid=C078415A103A3F40%211094&authkey=!ANE0-sqb5hAftiI </div>
\ 使用公式进行验证,假设某个key的供应量为 supply=100, 购买量为 amount=1, 计算价格:
$$ sum1=\frac{{(100 - 1) \cdot 100 \cdot (2 \cdot (100 - 1) + 1)}}{6} = 328350 $$
$$ sum2=\frac{{100 \cdot 101 \cdot (2 \cdot 100 + 1)}}{6}=338350 $$
summation = sum2 - sum1 = 10000,则价格为:
$$ \text{price} = \frac{\text{summation} \times 1 \text{ ether}}{16000} = \frac{10000 \times 1}{16000} = 0.625 $$
\ 数据来源::https://www.desmos.com/calculator/clnecohl2s
function buyShares(address sharesSubject, uint256 amount) public payable {
uint256 supply = sharesSupply[sharesSubject];
// 要求key的拥有账户购买第一个份额
require(supply > 0 || sharesSubject == msg.sender, "Only the shares' subject can buy the first share");
uint256 price = getPrice(supply, amount);
// 计算协议收取的手续费
uint256 protocolFee = price * protocolFeePercent / 1 ether;
// 计算key拥有者账户收取的手续费
uint256 subjectFee = price * subjectFeePercent / 1 ether;
// 检查交易金额
require(msg.value >= price + protocolFee + subjectFee, "Insufficient payment");
// 更新购买者的持有量
sharesBalance[sharesSubject][msg.sender] = sharesBalance[sharesSubject][msg.sender] + amount;
// 更新key的供应量
sharesSupply[sharesSubject] = supply + amount;
// 触发交易事件
emit Trade(msg.sender, sharesSubject, true, amount, price, protocolFee, subjectFee, supply + amount);
// 转账手续费给协议账户
(bool success1, ) = protocolFeeDestination.call{value: protocolFee}("");
// 转账手续费给key的拥有者账户
(bool success2, ) = sharesSubject.call{value: subjectFee}("");
require(success1 && success2, "Unable to send funds");
}
function sellShares(address sharesSubject, uint256 amount) public payable {
uint256 supply = sharesSupply[sharesSubject];
// 检查购买量
require(supply > amount, "Cannot sell the last share");
uint256 price = getPrice(supply - amount, amount);
// 计算协议收取的手续费
uint256 protocolFee = price * protocolFeePercent / 1 ether;
// 计算key拥有者账户收取的手续费
uint256 subjectFee = price * subjectFeePercent / 1 ether;
// 检查交易金额
require(sharesBalance[sharesSubject][msg.sender] >= amount, "Insufficient shares");
// 更新购买者的持有量
sharesBalance[sharesSubject][msg.sender] = sharesBalance[sharesSubject][msg.sender] - amount;
// 更新key的供应量
sharesSupply[sharesSubject] = supply - amount;
// 触发交易事件
emit Trade(msg.sender, sharesSubject, false, amount, price, protocolFee, subjectFee, supply - amount);
// 转账售卖收入到卖出者钱包
(bool success1, ) = msg.sender.call{value: price - protocolFee - subjectFee}("");
// 转账手续费给协议账户
(bool success2, ) = protocolFeeDestination.call{value: protocolFee}("");
// 转账手续费给key的拥有者账户
(bool success3, ) = sharesSubject.call{value: subjectFee}("");
require(success1 && success2 && success3, "Unable to send funds");
}
从购买和售出函数中可以看出在 Trade 事件函数签名中,供应量supply是当次交易之后的key供应量,在做链上数据分析时注意甄别。
\ \
本文撰写时friend.tech项目的链上数据:
数据来源:https://dune.com/cryptokoryo/friendtech
截至12月19日18: 00 ,friend.tech交易量已超过 1.5 万 ETH,累计完成了超过 1247万笔交易。在深入探讨了friend.tech项目的智能合约逻辑和经济模型后,可以看到这个项目在Web3领域展现出了显著的创新性和潜力。通过巧妙地结合区块链技术和社交媒体的动态,friend.tech不仅为用户提供了一个独特的社交平台,还开辟了一条新的路径,能够在去中心化环境中实现社交影响力的货币化。不过从10月开始交易量逐渐减少,也标示着项目的热度的逐渐降低,决定其产品是否可持续的因素是有影响力的用户是否愿意持续经营以创造价值,并最终转化为向外的能量,最终形成破圈效应。期待其后续的表现,期待更多的SocialFi赛道优质项目。
\ 声明:本文只做技术分享,不构成任何投资建议。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!