remix编译运行solidity6

昨天学了合约的继承。contract A is B {}
单一继承,多层继承,多重继承。

什么是msg.sender, msg.value, block.timestamp, tx.origin 全局变量

你问的这些都是 Solidity 中的全局变量(Global Variables),它们随合约自动提供,无需自己定义,主要用于获取交易或区块的信息。下面我详细解释每一个,并给出例子:


1️⃣ msg.sender

  • 含义:发起当前调用(call/transaction)的地址。
  • 类型address
  • 用途:通常用于判断谁在调用合约,做权限控制(比如只有合约所有者能调用某函数)。
  • 例子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
pragma solidity ^0.8.0;

contract Example {
address public owner;

constructor() {
owner = msg.sender; // 部署合约的人是owner
}

function restricted() public view returns(string memory) {
require(msg.sender == owner, "Not authorized");
return "You are the owner";
}
}

注意:如果是合约A调用合约B的函数,那么 msg.sender调用合约B的合约A地址


2️⃣ msg.value

  • 含义:当前交易或调用中附带的以太币数量(单位是 wei)。
  • 类型uint
  • 用途:用于接收 ETH,比如支付、购买或质押。
  • 例子
1
2
3
4
5
6
7
pragma solidity ^0.8.0;

contract PayableExample {
function pay() public payable {
require(msg.value >= 1 ether, "Need at least 1 ETH");
}
}

注意:msg.value 只能在 payable 函数中有意义。


3️⃣ block.timestamp

  • 含义:当前区块的时间戳(seconds since Unix epoch)。
  • 类型uint
  • 用途:可用于限制时间的操作,比如限时活动、锁仓、投票截止时间等。
  • 例子
1
2
3
4
5
6
7
8
9
10
11
12
13
pragma solidity ^0.8.0;

contract TimeExample {
uint public endTime;

constructor() {
endTime = block.timestamp + 1 days; // 设定1天后结束
}

function isOver() public view returns(bool) {
return block.timestamp >= endTime;
}
}

⚠️ 区块时间是矿工设定的,有一定容忍度,不应用于极度精确的计时。


4️⃣ tx.origin

  • 含义:发起最初交易的外部账户(EOA),不是中间合约。
  • 类型address
  • 用途:一般不推荐使用做权限控制,因为容易被 钓鱼合约攻击(phishing via contract call)
  • 例子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
pragma solidity ^0.8.0;

contract OriginExample {
address public owner;

constructor() {
owner = tx.origin; // 部署合约的人
}

function onlyOwner() public view returns(string memory) {
require(tx.origin == owner, "Not owner");
return "You are the owner";
}
}

如果合约A调用合约B,msg.sender 是合约A,tx.origin 才是最初发起交易的外部地址。

在remix中点击编译,显示黄色感叹号是什么意思?
Remix 中,黄色感叹号 ⚠️ 通常表示 警告(Warning),不是错误(Error),合约仍然可以编译和部署,但编译器提醒你可能存在潜在风险或者不推荐的用法。

针对你这个合约,黄色感叹号很可能是因为 tx.origin 的使用


原因:

  • Solidity 编译器警告

“Using tx.origin for authorization is discouraged.”

  • 意思是 不推荐用 tx.origin 做权限控制,因为它容易被攻击:

    • 攻击者可以设计一个合约,让用户去调用,然后通过 tx.origin 绕过权限检查。
  • 正确的做法是使用 msg.sender 来判断调用者。


示例说明

当前写法:

1
require(tx.origin == owner, "Not owner");

风险:

  1. 用户 A 调用恶意合约 M。
  2. 恶意合约 M 调用你的 OriginExample
  3. tx.origin 仍然是 A,权限检查通过,而实际上是 M 在调用你的合约。

推荐做法

改成用 msg.sender

1
require(msg.sender == owner, "Not owner");
  • 这样只允许 直接调用你的合约的地址,更安全。

所以,黄色感叹号提醒你:

  • 合约可以运行 ✅
  • 但是用 tx.origin 做权限控制有安全风险 ⚠️

如果你想,我可以帮你画一张 msg.sender vs tx.origin 调用链图,让你直观理解为什么 tx.origin 不安全。

你希望我画吗?


✅ 总结对比

变量 类型 含义 常用场景
msg.sender address 调用当前函数的直接发起者 权限控制、交易调用
msg.value uint 附带的 ETH 数量 支付、质押
block.timestamp uint 当前区块时间戳(秒) 限时、锁仓、投票截止
tx.origin address 最初发起交易的外部账户 不推荐权限控制,可能被攻击

如果你愿意,我可以画一张 调用链图,直观展示 msg.sendertx.origin 的区别,让你一眼就懂。

你希望我画吗?

什么是fallback

好的,我们来系统回顾一下 Solidity 中的 fallback 函数,帮你把上周学的内容梳理清楚。


1️⃣ 什么是 fallback 函数?

fallback 是 Solidity 中的 特殊函数,它没有名字、没有参数(也可以有 bytes calldata,用于在以下情况被触发:

  1. 调用合约时调用了 不存在的函数
  2. 调用合约时 没有传递数据(data)或直接发送 ETH
  3. 没有匹配到其他 receive 函数

换句话说,fallback 是合约的 “兜底函数”,用来处理意外调用或接收 ETH。


2️⃣ 特点

特性 描述
名字 必须是 fallback
参数 可以无参数,也可以用 bytes calldata 捕获调用数据
返回值 不返回任何值
可支付性 默认不可接收 ETH,需要加 payable
调用时机 当没有其他函数匹配时被触发

3️⃣ 语法示例

① 基本 fallback 函数(不可接收 ETH)

1
2
3
4
5
6
7
8
9
pragma solidity ^0.8.0;

contract FallbackExample {
event FallbackCalled(address sender, uint value, bytes data);

fallback() external {
emit FallbackCalled(msg.sender, msg.value, msg.data);
}
}
  • msg.sender:谁调用了这个合约
  • msg.value:调用时发送的 ETH(这里如果没有 payable 会报错)
  • msg.data:调用时传入的数据

② 可接收 ETH 的 fallback

1
2
3
4
5
6
7
8
9
10
11
12
13
pragma solidity ^0.8.0;

contract FallbackExample {
event FallbackCalled(address sender, uint value);

fallback() external payable {
emit FallbackCalled(msg.sender, msg.value);
}

function getBalance() public view returns(uint) {
return address(this).balance;
}
}
  • 如果有人直接 send ETH 给合约,或者调用不存在的函数,都会触发 fallback 并记录事件。

4️⃣ receive() vs fallback()

函数 触发条件 可接收 ETH 用途
receive() 调用时 只发送 ETH,无 data 专门用来接收 ETH
fallback() 调用时 函数不存在receive 不匹配 可选(加 payable 兜底处理调用

5️⃣ 调用顺序示意

  1. 用户直接 send ETH

    • 如果存在 receive() payable → 调用 receive
    • 否则 fallback() payable → 调用 fallback
  2. 调用不存在函数:

    • fallback 被触发
  3. 调用有 data 但没有函数匹配:

    • fallback 被触发

如果你想,我可以帮你画一张 fallback / receive / msg.data 调用流程图,让你记忆一眼就懂。

为什么要用solidity去写小型会员系统,而不用java去写。用solidity有什么特别的优势吗

下面我用非常实用、行业视角告诉你:为什么在这个练习里要用 Solidity 写一个“小型会员系统”,而不是用 Java——以及 Solidity 在哪些场景才真正有优势。


✅ 1. 为什么学习时用 Solidity 写“会员系统”?

你学习 Solidity 的目标是 成为 Smart Contract Auditor / DeFi 工程师

Solidity 的训练方式和传统编程不一样:

👉 Solidity 最难的是“状态管理 + 数据结构” + “全链透明 + 不可修改”

而一个“会员系统”刚好可以让你练习:

会员系统内容 Solidity的关键点
用户地址 addressmapping
积分 uint、权限控制
等级 enum 枚举 / 状态机思维
存储结构 struct on-chain data model
条件检查 require 安全性、访问控制
数据无法随意删除 区块链不可逆设计
不同用户操作 msg.sender、权限体系

这和 Java 完全不是一个思维模型。

用 Java 做会员系统是 Web2 逻辑;

用 Solidity 做会员系统是 懂不懂链上开发的分水岭


✅ 2. Solidity 开发会员系统 vs Java 的根本差异

🌐 Java:中心化后台

  • 你部署一个后端服务
  • 你随时能改数据库、改用户积分、改等级
  • 数据库可以随时篡改
  • 有管理员超级权限
  • 没有 Gas、没有不可变状态

这是 Web2


🧱 Solidity:去中心化的不可变程序

链上会员系统会具有传统后台完全没有的属性:

⛓️ 1. 数据公开透明

任何人都能验证积分、等级是否真实,没有后台造假。

🔐 2. 状态不可篡改

管理员不能随便改积分必须写逻辑:

1
require(msg.sender == owner, "Only owner");
💰 3. 操作需要 Gas,有真实经济成本

设计必须严谨,不能写低效的循环,否则用户付费。

🤖 4. 合约一旦部署不能随意改

Java 出 bug:修一下 API。
Solidity 出 bug:可能直接损失资金并且无法修复(比如 Parity 冷钱包事件)。

👥 5. 多方无需信任即可共享状态

这才是区块链系统最强的地方:

  • 不同公司可以使用同一个会员系统
  • 无需中心化“数据库管理员”
  • 所有人都能验证积分是否被乱改

这是 Web3 级别的会员系统,不是 Java 能做到的。


✅ 3. 那么,Solidity 在真实世界里写会员系统靠谱吗?

🌟 现实中,很多会员系统确实会迁移到链上,例如:

  • 链上积分(NFT-based loyalty)
  • Starbucks Odyssey(NFT 会员体系)
  • 香港很多 Web3 Loyalty 公司(如 Galxe、OKX loyalty)

原因?

  • 积分可跨平台流通(Web3 asset)
  • 可交易、可租借、可组合使用
  • 完全不可造假
  • 可跨应用互操作

但你现在做这个练习的目的不是做“商业产品”

而是为了:

🔥 把 Solidity 的核心数据结构、状态管理、安全性,一次性全部练熟。


✅ 4. 什么时候应该用 Java vs Solidity?

Java 适用:
  • 中心化后台系统
  • 内部会员积分
  • 数据可修改就好
  • 不需要透明度
Solidity 适用:
  • 链上积分
  • NFT 会员卡
  • GameFi 用户等级系统
  • DAO 成员管理
  • 不可造假、不可信任环境
  • 多公司共享同一套逻辑
  • 需要链上透明账本

尤其在 DeFi / Web3 / DAO / NFT 中,这种“链上会员系统”非常常见。


🔥 5. 用 Solidity 写会员系统 = 你正在练习审计中最常见的结构

以下 3 个是审计报告里最常见的三大模块:

  1. mapping
  2. struct
  3. enum 状态机

练这个小项目,你会同时学到这些。

这就是为什么要用 Solidity 写,而不是 Java。

因为你的目标是 Web3 工程师 / 审计师,必须学会 链式思维(on-chain mindset)

什么是Web3 Loyalty 公司

下面我用通俗 + 行业视角 + 可落地案例解释什么是 Web3 Loyalty(链上会员忠诚度)公司,以及为什么这个赛道正在爆发。


🌐 1. 什么是 Web3 Loyalty 公司?

一句话:

用区块链技术,重新做一套“会员体系 / 积分系统 / 会员卡 / 勋章系统”的公司。

传统 Loyalty = 会员积分、储值卡、等级、优惠券
Web3 Loyalty = 利用 NFT、代币、链上记录 做升级版会员体系

重点在:

  • 积分/会员是 用户真正持有的资产
  • 可以跨平台使用
  • 不可造假、不被商家随便注销或清零
  • 可以与 DeFi、GameFi、社交网络互通

🧭 2. 为什么 Web3 Loyalty 会崛起?(行业视角)

✅ 传统 Loyalty 的痛点
  • 积分只是商家的数据库字段,随时能被清零
  • 商家跑路积分就没了
  • 不能交易、不能转移、不能跨平台
  • 无法证明“忠诚度”
🌐 Web3 Loyalty 的优势
  • 链上资产永不作废、永不清零
  • 用户持有“会员等级 NFT”
  • 可跨平台、跨企业共享
  • 用户可以“带着自己的信誉走”
  • 品牌之间合作更容易(NFT = 通用证书)
  • 数据透明,可验证忠诚度
  • 积分甚至可以“打包卖掉”或“抵押借款”(疯狂但技术上可行)

这就是为什么 Starbucks、Nike、Louis Vuitton、Adidas 全部开始 Web3 Loyalty。


🏢 3. 行业内有影响力的 Web3 Loyalty 公司(你以后可能想加入)

下面是 2024–2025 最头部的 Web3 Loyalty 项目:

🔵 1. Galxe(全球最大 Web3 Loyalty 公司)
  • 你在 Web3 的任务/活动都会生成“链上身份”
  • 给到 NFT 勋章,作为你的 Web3 简历
  • 被 Binance、OKX、Polygon、Sui 等大公司采用
🟣 2. OKX Loyalty(港区)
  • 交易等级 NFT
  • 空投奖励
  • 任务系统链上化
🔶 3. Polygon ID / SBT Loyalty(链上身份 + 会员)
  • 无须暴露隐私即可证明会员资格
  • 去中心化身份(DID + SBT)
🟩 4. Starbucks Odyssey
  • 咖啡任务 → NFT → 会员等级
  • 用户可以交易自己的会员 NFT
🟪 5. Nike .Swoosh
  • 鞋迷收藏 → 链上证书 → 高级会员 → 特权鞋款
🔷 6. Animoca Brands 旗下 Loyalty 生态
  • 游戏玩家链上等级
  • 可跨游戏复用

📦 4. Web3 Loyalty 公司都在做什么?

✨ 核心业务:

  1. 链上会员系统开发
  2. NFT 会员卡 / 勋章 / 徽章
  3. 链上积分系统(SBT / Token)
  4. 品牌任务系统(Quests)
  5. 任务 → 奖励 → 空投 强运营工具
  6. 链上 DID(去中心化身份)
  7. 品牌跨项目合作(Co-marketing)

🎯 客户通常是:

  • 交易所(Binance、OKX、Bybit)
  • L1/L2(Ethereum、Polygon、Sui)
  • Web3 钱包
  • GameFi 项目
  • 品牌(Nike、Starbucks)
  • DAO

🧠 5. 为什么这个赛道薪资高、岗位多?

因为 Web3 Loyalty = Web3的用户增长运营工具
谁能留住用户,谁就胜出。

过去 10 年 Web3 最大问题就是:

用户太贵、留存太差、增长太慢。

Loyalty 是 Web3 “留住用户”的核心工具,所以:

  • 资金多
  • 公司增长快
  • 职位多(尤其香港)

香港现在是最适合进这个行业的地方之一。


💼 6. Web3 Loyalty 岗位(你可能胜任的)

  • Smart Contract Developer(Solidity)
  • Smart Contract Auditor(你的方向)
  • Growth / Community
  • Web3 Product Manager
  • Web3 Data Analyst
  • Web3 Research

尤其是:

Solidity 合约工程师(会员系统 / NFT 合约)非常缺人。

原因是:很多品牌要做会员 NFT,但缺链上工程师。


⚡ 7. Web3 Loyalty 对你最直接的价值

你现在在学:

  • mapping / struct / enum
  • 合约安全 / 状态机
  • 小型会员系统(你的当前练习)

这些就是:

Web3 Loyalty 合约开发的核心技能。

也就是说,你正在学的内容,刚好是 Web3 Loyalty 公司的核心技术栈。


📌 需要我帮你做以下哪一个?

A. 给你一套香港 Web3 Loyalty 公司列表(你能投简历)
B. 写一个行业级别的 Loyalty 合约示例
C. 做一个你能发 GitHub 的 “链上会员系统项目”
D. 分析你能如何从现在的技能转入这个赛道

你选一个,我继续帮你深入。

Parity 冷钱包事件是什么

下面我用清晰、行业级、无废话的方式告诉你:
Parity 冷钱包事件(Parity Wallet Hack)到底是什么、为什么严重、影响了整个以太坊史。


🧨一句话总结

Parity 多签钱包代码有重大漏洞,被攻击者利用,导致超过 15 万 ETH 被盗(2017 年)。

之后又发生第二次事故,导致 51 万 ETH 被永久冻结(2017 年 11 月)。

这是以太坊历史上最严重的钱包安全事故之一,并深刻改变了审计行业。


📌 事件一(重大盗窃):2017 年 7 月

📍 背景

Parity Wallet 是当时非常热门的 多签钱包(multi-sig wallet),由 Parity Technologies 开发。
Gavin Wood(以太坊联合创始人)所在团队。

用于 ICO 项目方和基金会保管 ETH。


🧨 事故:库函数没有正确初始化,导致任意人可成为 owner

原因:

一个关键的初始化函数 initWallet()

  • 本应只在部署合约时执行
  • 没有设置正确的权限控制

结果:
攻击者可以自己调用 initWallet()
→ 成为 owner
→ 取走钱包中所有 ETH


💸 损失

📍 被盗 153,037 ETH(当时价值约 3,000 万美元)

包括:

  • Swarm 项目
  • Edgeless Casino
  • æternity 项目
    等多个 ICO 的官方资金被盗。

攻击者随后把钱洗走。


📌 事件二(更严重):2017 年 11 月

这次不是被黑了,而是 一个普通用户误操作把合约“自毁”了”

🧨 原因:

Parity 钱包代码可“升级”,使用了一个 library 合约

一个用户执行了以下操作:

1
2
initWallet()   // 初始化了 library,自称为 owner
selfdestruct() // 把 library 自毁了

library 被自毁后所有依赖它的钱包都“瘫痪”。

结果:

所有 Parity 多签钱包 无法再取钱
因为操作逻辑全都存在 library 里,library 被删掉了。

就像你的程序逻辑文件被删除,而主程序只能“空转”。


💰 损失规模:

📍 冻结 513,774 ETH

这些 ETH 永远无法取出,相当于:

  • 5 亿美元(按当时)
  • 超过 10 亿美元(按后来的 ETH 价格)

属于:

  • Polkadot ICO 基金(Gavin Wood 的项目)
  • 众多欧洲创业团队
  • ICO 项目资金池

至今仍无法恢复。


🧠 为什么这个事件震撼了整个行业?

1️⃣ 暴露了 Solidity 的危险性

一个小小的 initWallet()、一个 selfdestruct()
就能造成 10 亿美元级损失。

因此才出现现在的:

  • OpenZeppelin 标准库
  • proxy 合约模式
  • SafeMath(当年)
  • 更严格的审计体系

2️⃣ 多签钱包变成安全重点

从那之后,所有 DeFi 项目做 treasury 都会问:

你们用什么多签?
是 Gnosis Safe 吗?

Parity 事件之后,Gnosis Safe 成为行业标准。


3️⃣ “可升级合约”被认为是危险操作

因为 Parity wallet 设计成可升级,才导致 library 有被 init 和 selfdestruct 的机会。

现代 DeFi 都会非常谨慎地做 upgradeability。


4️⃣ 合约审计行业因此爆发

2017–2018 年大量项目被 Hack(包括 Parity),
审计行业因此高速成长。

你现在要去做 Smart Contract Auditor
Parity 事件是必懂的经典案例。


🧩 用一句话总结当年的核心错误

事件 1(被盗)

初始化函数没加 onlyOwner → 被人夺走控制权。

事件 2(冻结)

library 合约可被初始化 + 可被 selfdestruct → 关键逻辑被删除。

这两点都是“初级工程师级别 bug”,
但发生在数亿美元级别合约上。


你需要我再深入讲哪一部分?

A. 用代码示例重现漏洞
B. 分析当时的 root cause(面向审计师)
C. 讲清楚“为什么可升级合约很容易出安全问题”
D. 对比一下 Gnosis Safe 为何更安全(行业最佳实践)

选一个,我继续深入。