基本信息

阅读时间:约 18 分钟

字数:约 7106 字

摘要:把合约风险拆成九个普通人能自查的入口:权限配置、预言机依赖、升级开关、调用顺序、价格滑点、清算机制、治理权限、审计覆盖与时间锁,逐一给出三分钟到三十分钟的检查动作与六个可量化指标。

全文语音

中文

English

日本語

한국어

1

九处自查点的来历:把「看不懂」拆成九个能动手的入口

陈默今年 34 岁,在上海一家做跨境物流系统的公司写了十一年后端代码。2024 年秋天的一个周末,他把家里三个钱包曾经授权过的合约地址整份导出来,排成一张表,一共四十七行。他盯着这张表看了两个晚上,能笃定说清楚的只有「授权额度」那一栏;剩下的「代理实现」「治理执行器」「喂价来源」这些词组在一起到底意味着什么,他说不上来。「那一刻我意识到,卡住我的不是看不懂 Solidity,是我不知道该从哪一个词开始查起。」

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 思维导图

后来他把这张表改成九列,每列写一个问题,每列后面跟一个能立刻执行的动作。这九列不是漏洞分类图——按学名分门别类的那种写法,颗粒度细到函数级别,是给审计人员跑扫描工具用的;一个普通人打开手机钱包,真正需要的不是「这一类叫什么名字」,而是「我点进去三分钟能不能得到一个是或否」。

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 配图

所以这份清单的排序逻辑是按时间成本递增排的:先查能在区块浏览器页面上直接看到的东西,再查需要翻文档的,最后才是必须读源码的。前三项——合约是不是代理结构、最高权限落在几个地址上、治理改动有没有等待期——加起来大约三到五分钟;中间三项需要读白皮书、审计报告和治理面板,大约十分钟;最后三项涉及函数调用顺序、成交价格偏差和清算触发条件,半小时起步。

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 配图

一个容易被忽略的前提是:九处自查给的是「动作」,不是「结论」。同样一个「最高权限落在单个普通账户」的配置,在一个上线两周、沉淀量很小的新应用里,和一个已经运行三年、沉淀量庞大的协议里,分量完全不同。清单的作用是把原本不可见的东西标出来,让每个人自己去权衡,而不是替任何人下判断。

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 配图

陈默现在每次接触一个新的合约,都会先花五分钟填这张表。「我不是在挑毛病,」他说,「我只是想知道,如果有一天真的出问题,它会从哪一道门进来。」下面九节,就是这九道门的进门方法。

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 配图
2

专业分析:九宫格风险雷达的量级分布与自检优先级

先看量级。据多家公开安全机构发布的年度事件汇编(来源类型:公开安全审计报告与链上事件数据库的年度汇总;口径说明:有的按事件次数计,有的按损失金额计),2021 至 2024 年间合约层损失的构成中,权限与访问控制相关条目长期停留在三成上下这个量级;价格操纵与预言机依赖类在一成到两成之间浮动;而重入类在更早几年占比更高,随着 0.8 版本编译器默认溢出校验与非重入修饰器的普及,近年下降到个位数百分比量级。金额口径会被个别巨额单次事件整个拉偏,所以看排序比看百分比稳妥。

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 框架图

于是有了这份清单的组织框架——九宫格风险雷达(9-Cell Contract Risk Radar,简称 9CRR)。它把九处自查点分到三条轴上:「谁能改」包含权限配置、升级开关、治理权限、时间锁四格;「数据从哪来」包含预言机依赖、滑点路由、清算机制三格;「代码怎么走」包含调用顺序与审计覆盖两格。三轴不是平均分的,是按「能被一个外部主体改变的可能性」排序的,这也正是上面那份统计给出的线索。

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 配图

和两种常见做法相比,9CRR 的差异很明显。第一种是线性清单:几十个条目从头念到尾,条目之间不分主次,念到第十条人已经疲劳,最后三条基本跳过。第二种是学术漏洞分类:边界清楚、颗粒细腻,但需要翻译成使用者的语言才能上手。9CRR 的做法是先分轴、再在轴上排优先级,允许一个人只走完「谁能改」这一轴就收手——这一轴恰好覆盖了统计里占比最大的那一类。

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 配图

真实案例能说明「同一个风险类型会换皮重来」。2016 年 The DAO 事件(公开披露,损失量级约 360 万枚以太,按当时价格计约五千万美元)是「对外转账早于状态更新」这一顺序被利用的经典样本,此后「先改账本、后转钱」的写法和非重入锁成为主流实践。2020 年一次借贷场景事件(公开复盘报告记载)则是另一条路径:先借出大额资产冲击单一现货池的定价,再利用依赖该价格的另一侧借出更多资产,两笔操作落在同一个区块内完成。两件事相隔四年、代码毫无关系,结构却是同一个。

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 配图

落到可执行的度量指标,六个数够用:权限单点掌控度(拥有最高权限的地址数量,理想不大于 1 且为多签,签名阈值不小于五分之三);变更留观时长(治理通过到实际执行之间的时延,48 小时是较常见的门槛);价格源冗余度(独立喂价来源不少于 2,聚合时去掉极值);偏差容忍值(单笔交易允许的最大价格偏差,0.5% 到 3% 可调);审计新鲜度(末次审计距今天数,与本次上线代码的差异行数比);清算可观察性(是否存在公开的触发接口与事件日志)。

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 配图

执行清单按顺序是:第一步在浏览器上确认是否为代理结构以及实现地址;第二步拉权限清单与拥有者个数;第三步查治理面板与时间锁参数;第四步核对喂价来源数量与更新频率;第五步打开审计报告,核对其覆盖的合约清单与代码版本是否和当前一致;第六步把上面六个数字写进自己的表格,三个月后重跑一遍。

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 配图
3

权限配置:钥匙有几把,分别开哪些门

合约里的权限不是一个开关,而是一串角色。常见的至少有:可以铸造的角色、可以暂停全部转账的角色、可以把实现指向别处的角色、可以调整费率参数的角色、可以把某个地址列入限制名单的角色。很多人在看合同时只问「有没有拥有者」,但真正要数的是「一共定义了几种只能被特定地址触发的行为」。在采用角色模型的合约里,这份列表通常能在区块浏览器上直接枚举出来。

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 对比图

第二个要数的是「每一把钥匙落在几个地址手上」。最需要注意的是最高权限落在一个普通外部账户——也就是某一个人手里的钱包——而不是多签合约上。多签的意义不在于多几道确认动作,而在于把一个关键动作从「一个人的决定」变成「多个人在异地分别确认」。常见配置是五个人里三个签名生效,签名人分属不同城市,各自用独立的硬件钱包保管私钥。

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 配图

第三个动作是看权限有没有交接和回收记录。一个长期运行的项目,权限往往会从团队账户改成多签,再从多签改成带时间锁的治理合约,一路减少人为单点。如果翻了半年记录发现权限从未变动过,也不必默认是好事——可能是稳定,也可能是没人再维护。这时候看这个合约最后一次被调用的日期,比看权限本身更能说明它的真实状态。

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 配图

陈默给这一步留的时间是九十秒:枚举角色、数拥有者、看最后调用时间。「我看权限的方式跟看公司公章一样,」他说,「不是问这枚章好不好看,是问它被谁锁在抽屉里、抽屉有几把钥匙、上一次拿出来用是什么时候。」

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 配图
4

预言机依赖:一个价格数字背后的四个环节

前端显示的价格,往往不是合约真正读到的那个数。一个价格从产生到被合约使用,中间至少经过四个环节:数据从哪里采集、怎么聚合成一个值、多久上一次链,以及合约读取时有没有检查这个值的更新时长。任何一个环节出问题,最终都会落到同一句「价格不对」上,但对应的补救手段完全不同,所以要分开查。

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 配图

采集环节看源头数量与来源类型。只用单个现货池的现价作为价格来源,成本最低,也最容易被一次大额交易在短时间内改变;把多个交易场所加权、或者改用一段时间内的时间加权平均价,抗操纵性会明显提高。查这一点不需要读代码,多数项目会在文档里写清数据来源;写得含糊的,可以直接在治理论坛里翻提案记录。

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 配图

更新环节看两个参数:一个是「偏离阈值」——新价格与上一次的差超过百分之多少才触发上链;另一个是「心跳时限」——距上次更新超过多少秒必须刷新。常见的组合是 0.5% 到 1% 的偏离阈值,搭配一小时量级的心跳。这两个参数决定了合约读到的价格有多新鲜,也决定了在市场剧烈波动的时候,它落后于真实行情多少。

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 配图

最后一环是读取侧的兜底。合约在取用价格时有没有检查这条数据的最后更新时间,有没有和第二个来源做交叉校验,有没有设定偏离过大时的熔断机制。这些保护措施平时完全看不见,只在极端行情里生效;正因为平时看不见,才需要在自查表里专门给它留一行——具体的检查方法是读取相应参数的值,确认它不是零、也不是一个明显不合理的数字。

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 配图
5

升级开关:合约可以改变自身意味着什么

链上常常给人一种「代码已经不可更改」的印象,但在主流的部署方式里,用户交互的那个地址往往只是一个外壳:真正的业务逻辑写在另一个合约里,外壳通过代理调用把请求转发过去。这种做法让修复缺陷成为可能,同时也意味着明天你交互的那份代码,未必是今天这一份。判断方法很简单:在区块浏览器打开合约页面,如果能看到与「读取代理实现」相关的标签,那就是代理结构。

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 配图

代理有几种常见实现形态:有的是把管理动作写在外侧的转发器上,有的是把升级函数写进逻辑合约本身,还有一种是按功能拆分模块的组合式结构。对使用者来说,形态之间的差别不是重点,重点是两件事:谁有权限调用那个把实现指向别处的函数,以及在调用发生之后,别人多久能察觉。

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 配图

第二个重点格外值得说:是否存在时间差。如果一次升级在发起的那一刻就立刻生效,那么从变化发生到做出反应之间的窗口是零;如果中间必须等待一段时间,就存在一个可以被观察、可以被响应的区间。这段等待期的长短,通常能在治理合约的参数里直接读出来,也是这份清单里少数几个能拿具体数字做横向对照的项。

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 配图

关于代理还有两个技术细节值得花十分钟:一个是初始化函数有没有在部署时被锁定,另一个是新旧实现的存储布局有没有发生位移。前者关系到「谁能扮演第一次设置的人」,后者关系到状态字段会不会被错位读取。两件事都不会在日常里出问题,可一旦出问题往往是大问题,属于典型的低频高影响自查点。

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 配图
6

调用顺序与重入:函数被第二次叫住的那一瞬间

重入这个词听起来很技术,实际场景却很生活化:你去窗口办事,工作人员先把东西递给你,然后才登记你已经取走。要是你能在登记之前绕回去再排一次队,就能拿到第二份。合约里的对应写法是「先把钱转出去,再更新账本」,而收款方如果也是另一个合约,它在收到钱的那一刻会触发一段自己的代码,这段代码完全可以选择立刻再调用一次取款函数。

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 配图

于是有了那句被反复引用的原则:先检查条件,先更新账本,最后才与外部地址交互。顺序本身不难理解,难的是「外部交互」未必只来自那个显眼的转账动作——某些代币标准在转账时会回调收款方提供的钩子函数,某些非同质化代币标准在转移时也会通知接收方,甚至连读取一个余额的动作,在被别的跳板函数调用时,都可能出现在意料之外的时机。

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 配图

除了同一个函数被重复进入,还有两类更隐蔽的情形:一类是跨函数重入,两个不同的函数共用同一份余额状态,从其中一个进入、从另一个退出;另一类是只读重入,某些函数虽然不改状态,却被其他协议当成价格来源读取,而在这个瞬间它的返回值并不真实。后者不需要造成任何直接的金额损失就能引发连锁影响,是近年公开复盘报告里反复出现的类型。

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 配图

自查这一步终究要靠读代码,但对不写代码的人并非完全无从下手。可行的办法是看项目有没有公开它采用的防护模式(例如函数级的互斥锁,或者检查、生效、交互三段式写法),有没有在审计报告里专门列出这一类问题的编号与处置结论,以及有没有公开且持续运行的赏金计划。这三项里有两项说不清的项目,通常意味着这块工作做得比较朴素。

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 配图
7

滑点与路由:屏幕上那个数字和成交价之间的距离

自动做市的池子大多遵循一条恒定乘积曲线:两种资产的储备量相乘保持恒定。这条曲线的形状决定了,交易额相对池子总量越大,成交价偏离中间价就越多——把交易规模压到池子的百分之一,价格冲击的量级大约在百分之二上下;压到十分之一,冲击会成倍放大。这就是为什么同一笔金额在深度不同的两个池子里,成交差价可能差出好几倍。

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 配图

第二个因素是路由跳数。从一种资产换到另一种,可以直接走一个池子,也可以经过中间资产分两跳完成。跳数越多,每一跳的冲击叠加越多;但反过来,如果每一跳都落在深度更好的池子里,总的冲击反而可能更低。这类选择由路由算法决定,普通人能做的一件事是:看清楚这笔交易最终经过了哪几个池子,而不是只看钱包给出的总额估算。

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 配图

第三个因素与区块内的排序有关,通俗说是有人在盯着尚未打包的交易,抢在前面做成一笔、紧跟着再做成一笔,把你夹在中间。由此产生的额外损失,本质是你的订单先把价格推了出去、再以推走之后的价格成交。应对的办法不是猜测,而是两个写法上的参数:允许的最大偏差比例,以及这次报价的有效截止时间。前者超过即撤单,后者超时即作废。

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 配图

这两个参数在多数交互界面上都能手动调整,默认值往往偏宽松,常见在 1% 到 3% 之间。把它们调严一点,代价是极端行情下更容易失败;调松一点,代价是更容易被夹在中间。这是一个纯粹的取舍,没有普适答案——但可以明确的是,把最大偏差设成接近百分之百,等于主动放弃了这道保护。「我不碰自己算不清的数字,」陈默说,「我只改那两个我看得懂的参数。」

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 配图
8

清算机制:被动离场是怎么被触发的

借贷场景里,健康因子是那条高压线。它由抵押品估值除以借款额得出,跌破 1 的时候,任何人都可以替你偿还债务并取走相应抵押品,作为回报获得一笔清算奖励。这套设计的本意是让协议不留坏账,但从使用者的角度看,它意味着存在一个公开、可被程序监控、并且谁都能抢先执行的离场机制。

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 配图

触发这一机制的三个输入,任何一个是被操纵的或者滞后的,结果都会失准:抵押品价格(就是上一节说的那个数字)、网络费用(费用高涨时,机器人可能放弃小额清算)、以及债务计息的方式。在极端行情里还能观察到一条自我强化的链条:清算人拿到抵押品后出售变现,出售动作进一步压低价格,压低的价格又触发下一批清算。

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 配图

清算奖励的设定决定了这条链条跑得多快。奖励太高,机器人会争相抢着执行,甚至在价格尚未真正恶化时就抢跑;奖励太低,则在网络拥堵时没人愿意出手,协议一端会短暂累积坏账。常见设计落在 5% 到 15% 这个区间,并配合部分清算——即一次只清算让健康因子回到安全线以上所需的那一部分,而不是一次性清空。

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 配图

自查的重点放在三处:健康因子的计算里有没有包含弹性较大的平台代币;借款利率是固定的还是随资金利用率浮动——浮动意味着有人可以通过改变池子规模来抬高你的利息成本;以及有没有公开的清算事件可供订阅。第三项最容易被忽略,也最便宜:把清算事件订阅打开,比每天盯着曲线看有用得多。

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 配图
9

治理权限与时间锁:改动生效之前留没留窗口

不少协议把关键参数写进治理流程,由代币持有者投票决定。这条路径本身是把权限从少数人手里分散出去的办法,但要看全四件事才完整:需要多少票才能提交提案、投票持续多久、通过后多久执行,以及是否存在绕过投票的特殊通道。前三个数字一般在文档里能找到,第四个往往藏在最新发布的合约权限清单里。

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 配图

法定人数是最容易被放过去的一项。门槛太低意味着极小的持有量就能推动重大改动,而真实的投票参与率通常在个位数百分比——这正是很多协议引入「委托」机制的原因:把投票权集中到长期参与者手上,以提高实际出席比例。查的时候重点看最近五次投票的实际参与率,而不是白皮书里写的那个理论门槛。

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 配图

第三个说的特殊通道,通常指紧急暂停或多签护卫,用于在发现问题时立刻冻结某个功能。这类机制在应急时非常有用,问题是它同时绕开了投票流程。值得留意的是它的能力边界:是能暂停提款,能单方面更改参数,还是仅限于停止新开仓——三种能力的影响差别巨大,而它们的区别往往只写在合约代码的某一行里。

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 配图

时间锁是把「从决定到执行」拉长的装置,常见设定为 48 小时到 72 小时。这段时间内,任何订阅了链上事件的人都能看到即将发生什么,并有时间安排自己的处置——这段可见性本身就是性价比最高的一道保护。陈默把这一项在表格里标了星号。「其他八项是能不能看懂的问题,」他说,「这一项是有没有时间反应。」

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 配图
10

审计覆盖范围:报告之外那些没被读过的行

一份审计报告回答三个问题:审了哪些合约、在什么时间点审的、发现了什么并建议怎么改。看报告的第一步不是跳到结论页,而是翻回范围章节,核对其中的合约清单是否包含你现在正在交互的那个地址——大量遗漏恰恰发生在这里,因为合约数量往往比人们以为的多,外围的辅助模块、收益分发器、跨链接入层都可能落在清单之外。

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 配图

第二步是核对代码版本。报告通常会记录被审代码在代码托管平台上的提交标识。如果之后又发生过多次代码更新,尤其是包含逻辑改动的更新,这份报告的对应关系就要打折。做法上可以直接比对:找到当前部署代码对应的构建版本,与报告里记录的那个提交点比较,看中间隔了多少次提交。

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 配图

第三步是看发现事项的分级与处置状态。报告一般把问题分为若干等级,并标注已修复、已确认、已忽略三种状态。「已忽略」不一定是坏事——有些问题确实属于不可修或不值得修的设计取舍,但知道它们被保留了,本身就是信息。更值得注意的是另一件事:如果报告里完全没有列出中等级以上的问题,通常说明范围偏窄,而不是说明代码完美。

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 配图

最后要说清审计不覆盖什么。多数审计针对的是合约代码本身,不覆盖前端网页,不覆盖运营层面的密钥保管流程,不覆盖与其他协议组合之后才出现的新情形,也不覆盖之后发生的代码更新。把这些「没被覆盖到的地方」单独列一行写进自己的表格,比只记一个「有没有审计报告」的勾,要更接近事实。

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 配图
11

把九处收拢成一张表:四步跑完自查

第一步,三分钟,全在区块浏览器上完成:确认是否为代理结构与实现地址、枚举权限角色与拥有者数量、查看治理时间锁参数、读取最近一次关键函数调用的时间。这四项不需要任何技术背景,也不需要打开代码编辑器,在手机上就能做完。

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 配图

第二步,十分钟,读文档:喂价来源与更新参数、清算规则与健康因子门槛、最近一次审计报告的合约清单与提交标识、治理投票的实际参与率。这四项里有任何一项找不到公开记录,就在表格里如实写「未公开」,不要凭印象补空——信息缺失本身就是一种结果。

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 配图

第三步,三十分钟,针对真正要投入的场景读关键源码:转账相关函数是否存在对外汇款早于状态更新的写法、取价函数有没有更新时长校验、初始化函数有没有被锁定、新旧实现的存储布局有没有位移。读不懂全部没关系,把这四个点单独拎出来看,比从头到尾通读一遍有效得多。

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 配图

第四步,长期订阅:把升级事件、权限变更事件、清算事件加入监听,设置邮件或推送提醒。九处之中随时间变化最快的是前四项,而它们恰好都能用事件订阅覆盖住。三个月重跑一次完整自查,日常靠订阅兜底,是大多数人能长期坚持下去的节奏。

把合约风险拆成九处:从权限、预言机到升级开关的自查清单 配图

做完这四步你会发现,真正消耗时间的从来不是理解某个技术名词,而是找资料的过程——很多信息并不难懂,只是散落在治理论坛、代码仓库、审计文件和区块浏览器这四个互不相通的地方。把它们抄到同一张表里,这张表就是你的答案。

FAQ

常见问题

1.问:我完全不懂代码,这份清单里有几项是能自己做完的?

答:前六项都不需要写码:是否为代理结构、权限落在几个地址、时间锁多长、喂价有几个来源、有没有审计报告、报告覆盖了哪些合约。做完大约十五分钟,在手机浏览器上就能完成。

2.问:九个自查点里,哪几个变化最快?

答:权限归属、实现地址、时间锁参数、治理参与率这四项。它们会随着团队调整、版本更新和投票结果频繁变动,适合用链上事件订阅长期跟踪;其余五项相对稳定,每季度复查一次即可。

3.问:看到审计报告里写着「未发现问题」,是不是就说明没有问题?

答:不能这样理解。报告的结论只在它声明的范围和时间点内成立。要核对三件事:范围里有没有你正在交互的那个合约地址、报告记录的提交点是否仍是当前版本、以及上一次代码更新距今多久。

4.问:时间锁设成零和设成两天,实际差在哪?

答:差在反应窗口。设为零意味着改动在发起的那一刻生效,所有人到同一秒才知情;设成两天意味着中间有一段公开可见、可查询、可用于安排处置的时间。这类差异不影响日常使用,只在你最需要时间的那一天显现。

5.问:九个都查完,就一定能避开损失吗?

答:不能。任何自查都只能降低「完全不知道会发生什么」的概率,不能消除合约层本身的技术不确定性。清单的作用是把不可见的部分显形,让人在自己的承受范围内做决定。

把不可见的部分标出来,比给出一个简单结论更有价值——因为结论会随着明天的一次代码改变而过时,而九个入口不会。


图片来源:图1 HarryHO34 / Pixabay (CC0) · 图2 tphananh / Pixabay (CC0) · 图3 cegoh / Pixabay (CC0) · 图4 wal_172619 / Pixabay (CC0) · 图5 geralt / Pixabay (CC0) · 图6 geralt / Pixabay (CC0) · 图7 geralt / Pixabay (CC0) · 图8 vaclavikm / Pixabay (CC0) · 图9 dragh / Pixabay (CC0) · 图10 pen_ash / Pixabay (CC0) · 图11 donauwood_de / Pixabay (CC0) · 图12 TerriAnneAllen / Pixabay (CC0) · 图13 lin2015 / Pixabay (CC0) · 图14 AnnaER / Pixabay (CC0) · 图15 reallywellmadedesks / Pixabay (CC0) · 图16 lin2015 / Pixabay (CC0) · 图17 Nennieinszweidrei / Pixabay (CC0) · 图18 Couleur / Pixabay (CC0) · 图19 Greyerbaby / Pixabay (CC0) · 图20 InTellIGentFan / Pixabay (CC0) · 图21 Tama66 / Pixabay (CC0) · 图22 A_Different_Perspective / Pixabay (CC0) · 图23 Couleur / Pixabay (CC0) · 图24 FilipFilipovic / Pixabay (CC0) · 图25 Pexels / Pixabay (CC0) · 图26 RemazteredStudio / Pixabay (CC0) · 图27 eak_kkk / Pixabay (CC0) · 图28 valentinsimon0 / Pixabay (CC0) · 图29 pixundfertig / Pixabay (CC0) · 图30 Pexels / Pixabay (CC0) · 图31 29277261 / Pixabay (CC0) · 图32 Bergadder / Pixabay (CC0) · 图33 pen_ash / Pixabay (CC0) · 图34 sasint / Pixabay (CC0) · 图35 DavidClode / Pixabay (CC0) · 图36 RonaldPlett / Pixabay (CC0) · 图37 Daisymupp / Pixabay (CC0) · 图38 Pexels / Pixabay (CC0) · 图39 jhenning / Pixabay (CC0) · 图40 SwidaAlba / Pixabay (CC0) · 图41 HarryHO34 / Pixabay (CC0) · 图42 Dieterich01 / Pixabay (CC0) · 图43 cegoh / Pixabay (CC0) · 图44 beauQ / Pixabay (CC0) · 图45 MiraCosic / Pixabay (CC0) · 图46 Dimhou / Pixabay (CC0) · 图47 MiraCosic / Pixabay (CC0) · 图48 focusonpc / Pixabay (CC0)


本文为信息分享与财商教育,不构成任何证券、期货或投资咨询建议,亦不构成个性化投资建议。市场有风险,决策需谨慎。

本文由 AI 生成,经人类主编终审。