0

抽象

抽象知识专题栏目,提供与抽象相关内容的知识集合,希望能快速帮助您找到有用的信息以解决您遇到的抽象问题。

分享

浏览

4485

文章

21

古代通缉令那么抽象 古人真的能够抓到犯人吗

全文共 615 字

+ 加入清单

古代通缉令那么抽象真能抓到犯人?

古代通缉令虽然抽象,但是古人还是可以抓到犯人的,因为一般通缉令上都会写清楚一些特征,再加上那个时候也会有着一些比较严格的户籍制度。

古代抓捕犯人的时候,虽然不能够保证所有的犯人全部都可以抓捕归案,但是大部分的情况下很少会有漏网之鱼,因为在抓捕时也会有一些诀窍,首先就会选择一些非常抽象的画像。好像看上去和罪犯本人没有什么关系,但是往往都会有各种特征,这就能够有效缩小搜索的范围。

这些画像的重点并不在于和罪犯有多么相像,而是去描述一些特征,在边上也会有年龄体型还有身高等等,如果犯人有瘸腿又或者是脸上有刀疤,那么在抓捕犯人的时候看到这些特征去比对,基本上就能够找出犯人。

这个诀窍其实就是靠老百姓的举报,在中国户籍制度早就已经延续几千年,在最早的时候也可以追溯到战国时期,在那个时候还会有连坐的制度,如果一家犯错,那么其余的人也会受到影响。为什么要选择这一种制度?其实也是为了让老百姓能够彼此监督,最终就能够维持社会的稳定。因为这一个制度也会让老百姓对于身边的一些陌生面孔特别的敏感,经常性都会盯着自己的家庭,以免出现问题。

所以在一片区域中突然出现一个陌生人,这一片区域的老百姓肯定能够认出来,所以从那个时候来看,人口的流动性还是非常小的。古代人大部分的情况下活动的范围都比较小,基本上都只是一个村庄这么大小,一旦出现一个陌生人,那么随时都可能会暴露行踪,因此也会有很多的老百姓为了自保就会马上选择举报。

展开阅读全文

抽象劳动是指什么

全文共 343 字

+ 加入清单

抽象劳动指的是撇开劳动的具体形式无差别的人类劳动。

抽象劳动没有质的差别,只有量的差别。虽然抽象劳动是价值的源泉,但并不等于价值,只有凝结在商品中才能够形成价值。从目的论所设定的要求来看,具体劳动是指人们的主动劳动方面,而抽象劳动指的是人的被动劳动方面。具体劳动是说明了工艺学的能动性,而抽象劳动是说明了商品社会的被迫经济合类性。如果从深层次的方面来说,这是属于“经济必然性”规定。

抽象劳动是商品价值的唯一源泉,在价值中是包含任何自然物质的原子。具体劳动以及抽象劳动在空间以及时间上都是不可分割的,性质相同的抽象劳动,所形成的是性质相同的价值,它表明的是劳动多少,劳动时间多少的问题,像老师上课的具体劳动是采用个体、讲授、讨论以及集体,而抽象劳动是老师上了多久的课、教会了学生多少的知识。

展开阅读全文

抽象劳动是价值的唯一源泉吗

全文共 411 字

+ 加入清单

抽象劳动是形成价值唯一源泉

抽象劳动,是指撇开劳动的具体形式无差别的人类劳动。抽象劳动没有质的差别,只有量的差别。抽象劳动是价值的源泉,但抽象劳动不等于价值,抽象劳动只有凝结到商品中才能形成价值。

因此,其不是关乎人的生产活动的自身的存在特性,而是关乎人作为存在者的类存在特性。这表明:人的生理耗费被裹进一种社会进程,并且,作为抽象的关系运动。亦即,从目的论设定的要求看,具体劳动指代人的主动劳动方面,而抽象劳动指代人的被动劳动方面。具体劳动说明了工艺学的能动性,抽象劳动则说明了商品社会的被迫的经济合类性。从深层次看,这是一种经济必然性规定。

具体劳动创造商品的使用价值,抽象劳动是撇开劳动的具体形式的无差别的人类一般劳动。抽象劳动是商品价值的唯一源泉。在价值中不包括任何一个自然物质的原子。抽象劳动没有质的差别,只有量的差别。需要注意的是抽象劳动是价值的源泉,但抽象劳动不等于价值,抽象劳动只有凝结到商品中才能形成价值。

展开阅读全文

抽象类必须要有抽象方法吗

全文共 408 字

+ 加入清单

抽象类可以没有抽象方法,但是如果你的一个类已经声明成了抽象类,即使这个类中没有抽象方法,它也不能再实例化,即不能直接构造一个该类的对象。抽象方法必须在抽象类中,所以抽象类中的方法都必须是抽象方法。

当一个方法为抽象方法时,意味着这个方法应该被子类的方法所重写,否则其子类的该方法仍然是abstract的,这个子类由于继承父类,拥有抽象方法,因此它也是抽象类,即声明为abstract。abstract抽象类不能用new实例化对象,abstract方法只允许声明不能实现。如果一个类中含有abstract方法,那么这个类必须用abstract来修饰,当然abstract类也可以没有abstract方法。一个抽象类里面没有一个抽象方法可用来禁止产生这种类的对象。

java中的抽象方法就是以abstract修饰的方法,这种方法只声明返回的数据类型、方法名称和所需的参数,没有方法体,也就是说抽象方法只需要声明而不需要实现。

展开阅读全文

冷抽象和热抽象又可以称为什么

全文共 497 字

+ 加入清单

抽象和热抽象又可以称为抽象派。抽象绘画是泛指二十世纪想脱离模仿自然的绘画风格而言,包含多种流派,并非某一个派别的名称:它的形成是经过长期持续演进而来的。但无论其派别如何,其共同的特质都在于尝试打破绘画必须模仿自然的传统观念。

拓展资料:

抽象派有热抽象和冷抽象之分,代表人物分别是康定斯基和蒙得里安,他们的画面中放弃了具体的内容和情节,突出运用线、面、点、色块、构图等纯粹的绘画语言表现内心的感觉、情绪、节奏等抽象的内容。康定斯基还为抽象绘画著述了大量的理论书籍,深刻的研究了形式语言对人的知觉产生的影响,他的理论对后世设计领域产生了重大影响。

区别:

1.热抽象,从艺术形象上看是点、线、形、色无规律地组合,或随意挥洒构成的作品,造型偏于繁复,画面比较杂乱,色彩起着重要作用,且有较强的运动感。

冷抽象从形象上看趋于简单化、单纯、大色块、几何形、规律化,具有现代和谐感,在多数作品中形式构成严谨起着重要作用。冷抽象绘画,大多显得安静。

2.热抽象创作,偏重于主观感情,是用来抒发感情,表达某种意趣、意念、幻觉等。

冷抽象不受主观感情和表象制约,从形式结构出发,以几何图形的结构取得艺术形式的纯粹美的价值。

展开阅读全文

抽象名词前加冠词吗

全文共 691 字

+ 加入清单

1.抽象名词前一般不加冠词

Time is precious.

时间是宝贵的。

Knowledge is power.

知识就是力量。(谚)

Practice makes perfect.

熟能生巧。f谚)

即使有词修饰也可不加冠词:

It’s nearly bed time.

差不多是睡觉时间。

It’s common knowledge that his life is in danger.

他生命垂危是人所共知的。

You’ve made good progress this year.

今年你进步很大。

2.但如果一个抽象名词不足用于一般意义,而是有特别涵义的时侯,可以加定冠词用一般意义(泛指)用于特殊意义(特指)

She has a passion for music.Some of the music is folk music

她热爱音乐。那音乐有些是民间音乐。

Time tries truth.He didn’t tell me the truth.

时间检验真理。他没有跟我讲真话。

Art lies in concealing art.It’s one of the arts of living.

艺术在于掩盖艺术。(谚)这是一种生活的艺术。

His Job was to collect information.The information was false.

他的任务是搜集情报。这项情报是假的。

3.在一定情况下前面还可加不定冠词,如:

1)表示“一种”,“一场”等:

Translation is an art.

翻译是一种艺术。

It was a just war.

这是一场正义的战争。

展开阅读全文

java中什么是抽象

全文共 828 字

+ 加入清单

一.抽象

在了解抽象类之前,先来了解一下抽象方法。抽象方法是一种特殊的方法:它只有声明,而没有具体的实现。抽象方法的声明格式为:

abstract void fun();

抽象方法必须用abstract关键字进行修饰。如果一个类含有抽象方法,则称这个类为抽象类,抽象类必须在类前用abstract关键字修饰。因为抽象类中含有无具体实现的方法,所以不能用抽象类创建对象。

下面要注意一个问题:在《java编程思想》一书中,将抽象类定义为“包含抽象方法的类”,但是后面发现如果一个类不包含抽象方法,只是用abstract修饰的话也是抽象类。也就是说抽象类不一定必须含有抽象方法。个人觉得这个属于钻牛角尖的问题吧,因为如果一个抽象类不包含任何抽象方法,为何还要设计为抽象类?所以暂且记住这个概念吧,不必去深究为什么。

[public] abstract class ClassName {

abstract void fun();

}

从这里可以看出,抽象类就是为了继承而存在的,如果你定义了一个抽象类,却不去继承它,那么等于白白创建了这个抽象类,因为你不能用它来做任何事情。对于一个父类,如果它的某个方法在父类中实现出来没有任何意义,必须根据子类的实际需求来进行不同的实现,那么就可以将这个方法声明为abstract方法,此时这个类也就成为abstract类了。

包含抽象方法的类称为抽象类,但并不意味着抽象类中只能有抽象方法,它和普通类一样,同样可以拥有成员变量和普通的成员方法。注意,抽象类和普通类的主要有三点区别:

1)抽象方法必须为public或者protected(因为如果为private,则不能被子类继承,子类便无法实现该方法),缺省情况下默认为public。

2)抽象类不能用来创建对象;

3)如果一个类继承于一个抽象类,则子类必须实现父类的抽象方法。如果子类没有实现父类的抽象方法,则必须将子类也定义为为abstract类。

在其他方面,抽象类和普通的类并没有区别。

展开阅读全文

Java中抽象类与接口的区别

全文共 1115 字

+ 加入清单

抽象类与接口紧密相关。然而接口又比抽象类更抽象,它们之间明显存在区别。那到底存在哪些方面的区别呢?下面小编给大家讲讲java中抽象类与接口的区别。

1、抽象类与接口的区别

1,抽象类里可以有构造方法,而接口内不能有构造方法。

2,抽象类中可以有普通成员变量,而接口中不能有普通成员变量。

3,抽象类中可以包含非抽象的普通方法,而接口中所有的方法必须是抽象的,不能有非抽象的普通方法。

4,抽象类中的抽象方法的访问类型可以是public ,protected和默认类型,但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型。

5,抽象类中可以包含静态方法,接口内不能包含静态方法。

6,抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是public static类型,并且默认为public static类型。

7,一个类可以实现多个接口,但只能继承一个抽象类。

8.接口更多的是在系统框架设计方法发挥作用,主要定义模块之间的通信,而抽象类在代码实现方面发挥作用,可以实现代码的重用。

2、抽象类

在面向对象方法中,抽象类主要用来进行类型隐藏。构造出一个固定的一组行为的抽象描述,但是这组行为却能够有任意个可能的具体实现方式。这个抽象描述就是抽象类,而这一组任意个可能的具体实现则表现为所有可能的派生类。模块可以操作一个抽象体。由于模块依赖于一个固定的抽象体,因此它可以是不允许修改的;同时,通过从这个抽象体派生,也可扩展此模块的行为功能。为了能够实现面向对象设计的一个最核心的原则OCP(Open-Closed Principle),抽象类是其中的关键所在。

小编推荐:抽象类运用实例

1.C++

为了让一个类成为抽象类,至少必须有一个纯虚函数。包含至少一个纯虚函数的类视为抽象类。

纯虚函数形式如下:

例如,类A有两个纯虚函数lock()、unlock()和一个虚析构函数:

将函数lock()和unlock()初始化为0使它们成为纯虚函数,没有0这个初使化器,它们仅仅是虚函数。

抽象类对于提供模式、蓝图和后代类遵循的原则有用,如果遵循了蓝图的语义,后代类的行为可能按抽象类提供者和使用者所期望的那样。

通过使用抽象类,C++程序员可以提供C++组件的规范,在它的构建中指导组件的实现者。

2.C#

抽象类提供多个派生类共享基类的公共定义,它既可以提供抽象方法,也可以提供非抽象方法。如果派生类没有实现所有的抽象方法,则该派生类也必须声明为抽象类。另外,实现抽象方法由overriding方法来实现。

4、接口

使用interface来定义一个接口。接口定义同类的定义类似,也是分为接口的声明和接口体,其中接口体由常量定义和方法定义两部分组成。

展开阅读全文

java中接口和抽象类的区别是什么

全文共 1743 字

+ 加入清单

对于面向对象编程来说,抽象是它的一大特征之一。在java中,可以通过两种形式来体现OOP的抽象:接口和抽象类。这两者有太多相似的地方,又有太多不同的地方。很多人在初学的时候会以为它们可以随意互换使用,但是实际则不然。下面,就让小编带大家去了解一下接口和抽象类的区别吧!

1.抽象类和普通类的主要有三点区别

1)抽象方法必须为public或者protected(因为如果为private,则不能被子类继承,子类便无法实现该方法),缺省情况下默认为public。

2)抽象类不能用来创建对象;

3)如果一个类继承于一个抽象类,则子类必须实现父类的抽象方法。如果子类没有实现父类的抽象方法,则必须将子类也定义为为abstract类。

2.接口

接口,英文称作interface,在软件工程中,接口泛指供别人调用的方法或者函数。从这里,我们可以体会到Java语言设计者的初衷,它是对行为的抽象。在Java中,定一个接口的形式如下:

接口中可以含有 变量和方法。但是要注意,接口中的变量会被隐式地指定为public static final变量(并且只能是public static final变量,用private修饰会报编译错误),而方法会被隐式地指定为public abstract方法且只能是public abstract方法(用其他关键字,比如private、protected、static、 final等修饰会报编译错误),并且接口中所有的方法不能有具体的实现,也就是说,接口中的方法必须都是抽象方法。

从这里可以隐约看出接口和抽象类的区别,接口是一种极度抽象的类型,它比抽象类更加“抽象”,并且一般情况下不在接口中定义变量。

3.接口和抽象类的区别

A.语法层面上的区别

1)抽象类可以提供成员方法的实现细节,而接口中只能存在public abstract 方法;

2)抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的;

3)接口中不能含有静态代码块以及静态方法,而抽象类可以有静态代码块和静态方法;

4)一个类只能继承一个抽象类,而一个类却可以实现多个接口。

B.设计层面上的区别

1)抽象类是对一种事物的抽象,即对类抽象,而接口是对行为的抽象。抽象类是对整个类整体进行抽象,包括属性、行为,但是接口却是对类局部(行为)进行抽象。举个简单的例子,飞机和鸟是不同类的事物,但是它们都有一个共性,就是都会飞。那么在设计的时候,可以将飞机设计为一个类Airplane,将鸟设计为一个类Bird,但是不能将 飞行 这个特性也设计为类,因此它只是一个行为特性,并不是对一类事物的抽象描述。此时可以将 飞行 设计为一个接口Fly,包含方法fly( ),然后Airplane和Bird分别根据自己的需要实现Fly这个接口。

然后至于有不同种类的飞机,比如战斗机、民用飞机等直接继承Airplane即可,对于鸟也是类似的,不同种类的鸟直接继承Bird类即可。从这里可以看出,继承是一个 "是不是"的关系,而 接口 实现则是 "有没有"的关系。如果一个类继承了某个抽象类,则子类必定是抽象类的种类,而接口实现则是有没有、具备不具备的关系,比如鸟是否能飞(或者是否具备飞行这个特点),能飞行则可以实现这个接口,不能飞行就不实现这个接口。

2)设计层面不同,抽象类作为很多子类的父类,它是一种模板式设计。而接口是一种行为规范,它是一种辐射式设计。什么是模板式设计?最简单例子,大家都用过ppt里面的模板,如果用模板A设计了ppt B和ppt C,ppt B和ppt C公共的部分就是模板A了,如果它们的公共部分需要改动,则只需要改动模板A就可以了,不需要重新对ppt B和ppt C进行改动。

而辐射式设计,比如某个电梯都装了某种报警器,一旦要更新报警器,就必须全部更新。也就是说对于抽象类,如果需要添加新的方法,可以直接在抽象类中添加具体的实现,子类可以不进行变更;而对于接口则不行,如果接口进行了变更,则所有实现这个接口的类都必须进行相应的改动。

4.抽象类

抽象方法必须用abstract关键字进行修饰。如果一个类含有抽象方法,则称这个类为抽象类,抽象类必须在类前用abstract关键字修饰。因为抽象类中含有无具体实现的方法,所以不能用抽象类创建对象。

展开阅读全文

Java中抽象类与接口的区别

全文共 1598 字

+ 加入清单

抽象类和接口java语言中对于抽象类定义进行支持的两种机制,正是由于这两种机制的存在,才赋予了Java强大的面向对象能力。抽象类和接口之间在对于抽象类定义的支持方面具有很大的相似性,甚至可以相互替换,因此很多开发者在进行抽象类定义时对于抽象类和接口的选择显得比较随意。其实,两者之间还是有很大的区别的,那么它们之间有什么区别呢?下面,小编带你去了解一下。

1、抽象类和接口的编程区别

从编程的角度来看,抽象类和接口都可以用来实现"design by contract"的思想。但是在具体的使用上面还是有一些区别的。

1、抽象类在Java语言中表示的是一种继承关系,一个类只能使用一次继承关系。

但是,一个类却可以实现多个接口。也许,这是Java语言的设计者在考虑Java对于多重继承的支持方面的一种折中考虑吧。

2、在抽象类的定义中,我们可以赋予方法的默认行为。

但是在接口的定义中,方法却不能拥有默认行为,为了绕过这个限制,必须使用委托,但是这会 增加一些复杂性,有时会造成很大的麻烦。

3.在抽象类中定义默认行为,一旦抽象类中的行为方法发生改变,就会影响继承他的子类。

但是另一个方面,如果不利用抽象类中定义默认行为,就会导致同样的方法实现出现在该抽象类的每一个派生类中,违反了"one rule,one place"原则,造成代码重复,同样不利于以后的维护。

因此,在抽象类和接口间进行选择时要非常的小心。

2、抽象类和接口的设计理念区别

上面主要从语法定义和编程的角度论述了抽象类和接口的区别,这些层面的区别是比较低层次的、非本质的。现在小编将从另一个层面,即抽象类和接口所反映出的设计理念,来分析一下二者的区别。小编认为,从这个层面进行分析才能理解二者概念的本质所在。

抽象类在Java语言中体现了一种继承关系,要想使得继承关系合理,父类和派生类之间必须存在"is a"关系,即父类和派生类在概念本质上应该是相同的(参考文献〔3〕中有关于"is a"关系的大篇幅深入的论述,有兴趣的读者可以参考)。

对于接口来说则不然,并不要求接口的实现者和接口定义在概念本质上是一致的,仅仅是实现了接口定义的契约而已。为了使论述便于理解,下面将通过一个简单的实例进行说明。

考虑这样一个例子,假设在我们的问题领域中有一个关于Door的抽象概念,该Door具有执行两个动作open和close,此时我们可以通过抽象类或者接口来定义一个表示该抽象概念的类型,定义方式分别如下所示:

使用抽象类方式定义Door:

abstract class Door {

abstract void open();

abstract void close();

}

使用接口方式定义Door:

interface Door {

void open();

void close();

}

其他具体的Door类型可以extends使用抽象类方式定义的Door或者implements使用接口方式定义的Door。看起来好像使用抽象类和接口没有大的区别。

3、抽象类与接口语法定义的区别

在语法层面,Java语言对于抽象类和接口给出了不同的定义方式,下面以定义一个名为Demo的抽象类为例来说明这种不同。

使用抽象类的方式定义Demo抽象类的方式如下:

abstract class Demo {

abstract void method1();

abstract void method2();

使用interface的方式定义Demo抽象类的方式如下:

interface Demo {

void method1();

void method2();

}

在抽象类方式中,Demo可以有自己的数据成员,也可以有非abstarct的成员方法。

而在接口方式的实现中,Demo只能够有静态的不能被修改的数据成员(也就是必须是static final的,不过在interface中一般不定义数据成员),所有的成员方法都是abstract的。

从某种意义上说,接口是一种特殊形式的抽象类。

展开阅读全文

抽象画应该怎么欣赏?想看懂抽象艺术其实并不难

全文共 4003 字

+ 加入清单

说起抽象画我们肯定都会知道毕加索,也许我们并没有好好欣赏过他的画,但这个标签我们还是知道的。抽象艺术是在20世纪兴起于欧美,可能我们大多数人更加接受传统的具象艺术,毕竟画的是什么我们一眼就能看的出,如果不像的话我们就会他的他画的不好。但是抽象艺术一般人是不知道去怎么欣赏的,因为什么东西都不像,而且不知道作者想要表达什么。那抽象艺术到底应该怎么去欣赏呢?下面就给大家讲讲几个小例子。

不知道大家发现没有,我们欣赏油画的时候,会说“哇,这个色彩搭配的好棒”;欣赏国画时,会说“这个意境渲染的很到位”;可是,当我们遇到抽象画的时候,就只会来一句“看不懂”。

其实,抽象艺术最为致命的还不是看不懂,而是它难以表述。就好比你家墙上的壁纸有很多花纹,看起来很美很协调。可如果有人问你为什么好看?你也很难描述的清楚。我想,抽象艺术便是如此。

和其他作品比起来,欣赏抽象艺术时可依据的东西很少,没有什么规律可言,但这正是它的魅力所在。今天,我们就来聊聊这个我们看不懂的抽象艺术,或许当你今后遇到抽象作品时,可以增加一些谈资。

抽象艺术其实并是一个单独派别的名称,而是包含了很多画派。这些画派大致可以分为两类,一类为冷抽象,也可以称其为几何抽象,以蒙德里安、罗斯科和马列维奇为代表;另一类为热抽象,也可以称其为抒情抽象,以康定斯基、波洛克和德库宁为代表。

蒙德里安(1872%20-%201944)

在这些人中间,蒙德里安和康定斯基分别可以算得上是“冷抽象”和“热抽象”的鼻祖。他们都出生在%2019世纪下半叶,年龄相差%206%20岁,又各自在%2040%20岁获得艺术上的天启,而最后同样都于%201944%20年逝世。

然而康定斯基与蒙德里安,一生却鲜有交情。他们一个生于俄罗斯,一个生于荷兰,却被抽象一词紧紧地串联在一起。他们不约而同地,致力于探寻艺术的哲学意义与精神深度。而这两条看似平行的生命线,却在某些时刻交错相会,各自在艺术史上留下了不可磨灭的足迹。

瓦西里·康定斯基(Wassily Kandinsky)1866 年 12 月 4日出生于莫斯科的一个知识分子家庭。中学时代的康定斯基,不但成绩优异,而且是优秀的业余大提琴手和画家。他从小就长期浸润在音乐、诗歌和戏剧中,让他有着极好的修养。

他在莫斯科大学学过法律和经济,不仅取得法学博士学位,甚至还已经获得了一所大学的教授席位。或许在骨子里,康定斯基仍旧是一名学者和知识分子。

只是艺术对他的吸引力太过强大,以至于到了而立之年的康定斯基,竟毅然放弃令人羡慕的教授职位,背井离乡前往慕尼黑一心学画,这也照见了他儒雅外表下深藏的魄力和激情。

康定斯基在慕尼黑快速地成长起来。他一下子就被弥漫在这个城市的新艺术运动的气氛牢牢抓住。他一面如饥似渴地尝试各种艺术风格,另一方面则热衷于各种艺术运动,组建艺术社团。

德国著名的表现主义美术社团“青骑士”,最核心的人物就是康定斯基。事实上,青骑士不是艺术运动,也不是学派,没有明确纲领,只是画家的松散组织。

他们关心的是艺术形式,关心自然现象背后的精神世界。他们主张用绘画表现来巩固人类的精神。而事实证明,青骑士社有关“自然是精神世界根本源泉”的理念,对康定斯基抽象风格的发展,起到了至关重要的影响。

2. 蒙德里安

和康定斯基比起来,蒙德里安似乎早早就立下了自己的艺术之志。彼埃·蒙德里安(Piet Mondrian)1872 年 3 月 7日生于荷兰中部的阿麦斯福特,排行老二。他的父亲是一位清教徒和热衷美术的小学校长,环境条件使蒙德里安从小就能接触美术。

八岁时,蒙德里安就立志要当画家,但是家人认为艺术家是一项不稳定的工作。在与父母多次商量之后,蒙德里安承诺要取得美术教师资格,来养家糊口,这才让父母答应让他学画。

从成长的环境来看,蒙德里安一家都是虔诚的加尔文教派信徒。父母对蒙德里安的管教较为严厉,使得他在成长中渐渐学会那些自我约束、诚实朴素的清教徒式的生活作风。

在有些人看来,蒙德里安这种传统性格,与他未来的职业有些格格不入,但又或许正是这样的性格,帮助他创造了之后以“理性”和“极简”闻名世界的“新造型主义”画风。

39岁那年,蒙德里安丢下他的未婚妻,以及业已成熟的事业,离开荷兰前往巴黎当艺术家。为了表达自己的决心,他硬生生从自己的名字“Mondriaan”中减去一个“a”以誓转型。

尽管有艺术批评家,把蒙德里安形容成一个略带怪癖的独身主义者,但在巴黎的时间,确实让他的成就感与日俱增,因为蒙德里安的艺术进入了一个让人兴奋的高产期,而这是也他梦寐以求的。

事实上,蒙德里安对当代抽象艺术和建筑设计的影响,远远大于他同时期的很多艺术家。他打破了我们认为理所应当的现象:绘画总在平面上进行。每一条倾斜的线对他来说,都涉及了透视原理。在蒙德里安那里,空间在平面中是自我独立的。

鲜有人知道,得名于“冷抽象”的蒙德里安,其实还是一个热情的舞蹈迷。他甚至瞧不上多愁善感的探戈,而钟情于爵士,特别崇尚奔放火热的查尔斯登舞。而画笔、颜料、留声机、唱片,以及跳跃的舞步,共同组成了1920 年代中期的蒙德里安的生活。

3. 他们的 40 岁

1906 年和 1912 年对于康定斯基和蒙德里安来说,有着各自不同寻常的意义。相同的是,他们分别在那两个年份,步入了各自的不惑之年。

1906年对于法国文艺界而言,本来就不平常。那一年,著名的法国后期印象派大师塞尚去世。同样在那一年,康定斯基在巴黎及其附近度过了一段极其关键的岁月。在那里,他不断感受到来自野兽派画风的强烈震撼。

西方有观点认为,正是康定斯基那一年的法国之旅,促使他脱离了他的早期作品风格——新分离派,从而昂首成为一名真正独立的艺术家。

在随后的几年里,康定斯基先后完成了他的第一部关于抽象艺术的重要理论著作《论艺术的精神》,他的第一幅抽象作品《即兴》(又名,《第一幅抽象水彩》),组建了“青骑士”社团,并出版了《青骑士年鉴》。

《即兴31号》

《即兴》的伟大之处在于它的无结构性,这一点和以往的画面处理完全不同。因为马蒂斯和毕加索是通过将人物、风景和静物进行变形,使它们产生一种陌生感和新鲜感。而这幅作品看上去根本就没有造型,好像还没有完成,因为它是彻底的抽象。

康定斯基之后创作的《构图》系列成为了他的代表作,其正是采用了《即兴》的绘画语言,并最终将它拓展成为一首史诗。

《构图》

1912年也是西方艺术史上的一个重要年份。那一年,尽管传统的准则既没有被刻意地边缘化,也没有遭到最终的摒弃,但抽象之风已悄然刮起。那一年也是蒙德里安只身来到巴黎的第二年。

此前一年,蒙德里安见识了毕加索和布拉克等立体派的作品,极为震撼。立体派讲究的立体事实和明确客观,也都是蒙德里安追求的目标。但他也明白,立体主义只是他艺术旅途中的一个港湾,而不是终点。此后的抽象作品很快走向成熟。

蒙德里安《灰色的树》

1911 年,蒙德里安画了习作《灰色的树》,画中的树带有一些椭圆形构图,这是模仿了毕加索与布拉克的立体派风格,带有不少具象的元素。

而他在 1912年创作的相似尺寸的树系列习作《花丛中的苹果树》中,虽然大致构图和《灰色的树》很相像,但已经明显更加抽象,更具形式感,画面被一个个小的块面鱼鳞般拼接起来。

蒙德里安《花丛中的苹果树》

4. 他们是思想家

如果说布拉克、毕加索、莱热、德劳奈和马蒂斯首要的身份是画家,那康定斯基和蒙德里安便是画家和思想家。

对这两位艺术家来说,他们考虑的不仅是给绘画注入新意,更是整个人类的生存状态,他们认为人必须改观自身,而整个人类也正朝着物质与精神的更高阶段迈进。

在他们眼中,艺术家就是那个积极筹备黄金时代,进而宣布其到来的最佳人选。这也是为什么创作出来的作品,和创作作品的人必须保持一致。毕竟,如果没有一个一同进步的内心世界,艺术的演进将无从谈起。

对于内心世界的修炼,康定斯基在其著名的《论艺术的精神》一书中犀利地指出:精神如同肉体,能够通过经常锻炼而得到加强。艺术家天生的情感才华,不能将其埋入尘俗之中,而是要懂得如何陶冶精神。

事实上,他们的艺术观念或许也和当时的时代背景有关。19世纪中下叶,迅速发展的工业化进程给社会带来了巨大的变化,科技的进步、社会的变革、贫富的悬殊,各种政治问题、宗教问题、环境问题激荡着敏感的文学家和艺术家们。

在艺术之都巴黎,一时间聚集了大批现代艺术先驱,掀起了一场以巴黎为中心的轰轰烈烈的现代艺术运动。他们要为绘画寻找一条新的出路,以反映、适应或逃避动荡的社会现实。

蒙德里安也是其中的一份子。在他看来,生活本质上是简单的,而简单才是人类的完美境界。他认为,艺术应根本脱离自然的外在形式,以表现抽象精神为目的,追求人与神统一的绝对境界。

是的,作为冷抽象的缔造者,作为第一个将绘画提炼成几条线、几块三原色的开山者,蒙德里安看似简单的画面,实则是经过深思熟虑的,这点从他的画面制作中就能看出。

他那看上去单一的色彩,从来不是现成颜料直接挤出来了事,而是各种颜料混合后细腻层叠出来的效果;那些貌似重复的直线和几何图案,也是他手工精心绘制的。他并没有用尺,也没有套用任何格式去进行批量化生产。

他可以在经纪人来买画的时候,气定神闲地让他再等等。因为这幅画还没有完成,不够完美,一小块蓝色还要再上一遍色,而这一磨就是一年。这种淡定的背后是一种艺术追求,追求的或许正是某种深层的内在精神表达。

康定斯基与蒙德里安一个”热“,一个“冷”;一个绝对自由,一个绝对理性;一个代表了强烈的躁动,一个又充满了极度的耐心。如果说康定斯基是用音乐,打通了建筑和绘画的隔阂,那么蒙德里安则是用理性的艺术和思维,建构了传统与现代、艺术与设计和建筑之间沟通的桥梁。

而他们看似代表了两种截然不同的态度,却又在不经意间产生了那么多遥远的交会。他们在探寻艺术的哲学意义与精神深度方面不谋而合,共同构成了平行而交错的抽象双星。

展开阅读全文

婴儿也许天生具有抽象数字理解力

全文共 209 字

+ 加入清单

一项美国研究表明,婴儿在学会说话之前,可能能够理解抽象数字概念。

杜克大学的伊丽莎白·布兰诺和其他人让20个7个月大的婴儿听两个或三个女人说“看”,同时观看两个女人说“看”和三个女人说“看”的视频。研究人员发现,婴儿更有可能观看与说话女性数量相当的视频。布兰诺和其他人认为,在学习“数字”的概念之前,婴儿可以把他们听到的声音的数量和他们看到的图像的数量联系起来,这表明还没有掌握语言技能的儿童有一个识别数字概念的系统。

展开阅读全文

让抽象数学生活化

全文共 322 字

+ 加入清单

罗福田区教育研究中心研究员,小学数学研究带头人。她主持的“小学数学教学策略研究”被列入广东省教育研究“十五”计划,并获得广东省第六届教学成果一等奖。

华福小学的李京为他的父母写了“20万投资和价值保存计划”。学校的知望同学写了一篇关于为什么彩票有吸引力的小论文。然而,华新小学的叶美彤在分析了电话号码设置后,写下了“有趣的电话号码”。罗的教学策略给了孩子们进入数学王国的金钥匙。数学不仅仅是一堆数字、公式和定理,它还能让孩子们关注充满生活情趣的日常问题,包括团队游戏、财务规划、生活设计等。

罗的研究总结出15条教学策略,将生活中的问题引入课堂,使数学问题生活化、情境化。这些成果被编成专著在全区推广,对全区小学数学教学产生了直接的指导和促进作用。

展开阅读全文

六鳌抽象画廊

全文共 480 字

+ 加入清单

六鳌抽象画廊为国家AAA级旅游景区。

六鳌抽象画廊位于六鳌半岛东部的崂岈山,东临台湾海峡,西面是崂岈山,南北均是连坝风景沙滩和林带。景区距同三高速公路赵家堡互通口约35公里。

崂岈山是一处海蚀风化花岗岩地质地貌海岸景观。这里的岩石经千万年的海浪风沙洗礼,特殊的矿物质形成棕红色的纹理,在四通八达的沟壑间呈现出绚丽多姿的图形,迎面是画,移步即景,变幻莫测,扑朔迷离,宛如现代抽象画派的艺术杰作,被中科院地质专家命名“抽象画廊”。裸露在山坡上的岩石,呈现“绵羊沉思”、“灵龟出海”、“八戒娶亲”、“海狮私语”、“乳燕振翅”等动物形态,栩栩如生,形象逼真。海岸边平缓而优质的黄金沙滩和葱郁的防风林带,格外壮阔清新。中国科学院的有关专家赞誉这里是“国内罕见的奇特景观”,“旅游资源精品”,是开发滨海旅游度假区的理想选择地。黄金沙滩区总长约9公里,可开发滨海浴场、沙滩运动等项目。红石区,一块块红色或褐色的石头,色彩斑斓;奇石区,裸露在山坡上千姿百态的岩石,维妙维肖;抽象画廊区的景观更是天下一绝,大自然的鬼斧神工造就了一幅幅美仑美奂的抽象岩画。

景点位置

福建省漳浦县六鳌半岛

展开阅读全文

如何拍摄抽象艺术照 抽象艺术照5个拍摄技巧

全文共 819 字

+ 加入清单

你在观看别人拍摄抽象艺术照后,是否感觉非常有趣,其实掌握了技巧,你也可以拍出来,下面就来介绍下关于抽象艺术照的5个拍摄技巧吧!

(一) 移动你的相机

初学习摄影时,「拍出清晰的相片」是一个很重要的技巧,但有时不妨把快门刻意放慢,并有目的地移动相机,这样可以拍出更具艺术性的相片!但在拍摄时需要留意:

快门过慢会导致过曝,需要调小光圈和降低ISO 移动时最好按「轨迹」来移动(例如垂直或转圈),否则相片有机会变得过份杂乱 同一个场景,可以尝试快一点或慢一点的快门,可以拍出不同的效果!

(二) 拍摄移动中的物件

跟第一点差不多道理,也是透过「移动」来拍出艺术性的相片,但这次不是移动自身的相机,反而是去拍摄「移动中的物件」,例如行走中的汽车、玩耍的小狗等,相机的快门可以按照物件移动的速度来调整,若果移动中的物件速度很快,相机的快门不用过慢,否则整张相片会给得很模糊(除非你是刻意这样做)。若果在按下快门的一刻相机(你)跟着物件的方向移动,背景便会变得模糊而主体清晰,这个便是「Panning」的技巧了!

(三) 拍下干净的画面

要拍出具艺术感的相片,去除相片中不要的东西,拍下非常干净的画面也是一个好方法!其中一个很有用的技巧便是利用长焦镜头拍摄大环境中的小部分,例如整个沙滩中的一个小浪花,或是其他常见物件的一个小范围,也可以达到相同的效果,如果拍出来的画面是简洁、单一色调,或是具备有趣纹理的话更好啊!

(四) 透过其他物件来拍摄

「穿过其他物件来拍摄」也是一个常用的技巧,该物件可以是胶瓶、玻璃,甚至是树叶间、草丛、液体等也可以!让你的创意随便发挥吧!

(五) 善用多重曝光

现在很多数码相机也具备「多重曝光」(Multiple exposure) 的功能,只要你开启有关选项,再连续拍下两张或更多物件,让不同的画面同时曝光在同一张相片上,这样组合起来也会变得更抽象和具艺术感!但要留意一点的是,在拍摄时需留意保留黑色/偏暗的地方来让下一张相片曝光啊!

展开阅读全文

Photoshop制作抽象风格的同心圆艺术视觉海报

全文共 934 字

+ 加入清单

今天为大家分享photoshop制作抽象风格同心圆艺术视觉海报教程,教程很不错,值得大家学习,也很有创意,大家看过之后能有所帮助!

很多人以为,做一个PS高手就是需要用到各种复杂滤镜,最后把图片变得面目全非才好。而在我看来,软件的背后是创作者的心。把PS视作一件玩具,其实就是几个简单的几何形,也能玩出不同的花样。其中,抽象艺术的表达法可以拿来一用,仅仅是一些形状、色彩就能创作出让人耳目一新的视觉感受。

最终效果:

同心圆

STEP 01

你一定听过,人脸是最吸引眼球的画面。先准备好相应的人像素材。再打开PS,创建一个尺寸为1800*1200的文档。

STEP 02

画出三个圆,第一个圆是一个实心圆,第二、三个圆是空心的圆环。总之让它们看上去像一个靶心。它们的大小比例可以参考下图。

STEP 03

将准备好的人像图片导入到文档内,这时,复制两次,也就是让人像也变为三个。这样让人像与上一步中的圆形保持一一对应的关系。

STEP 04

关闭三个圆形的可见,这时,将这几个圆的“形”作为与其对应的人像图层的蒙版。当然,由于是三个不同的形,它们之间的关系就不能太平铺直叙,你一定懂得利用这三个不同的“形”创造一种有趣的错落关系。

STEP 05

可以利用调整图层工具对整个画面的色调进行修饰。

自制抽象画笔

STEP 06

这里我们将要分享一个快速自制抽象画笔的方法,再新建一个800*600的文档,背景为透明。在这个文档中画上一条矩形,然后复制多次后,均匀排布,只是保持左右端非对齐。如下图所示。

STEP 07

将这些条状矩形旋转-40度。旋转后得到的形状定义为画笔,进入【编辑>定义画笔预设】,确认了画笔名称后,点击确定即可。这个画笔是一个非常容易制作同时又能很好表达现代感的元素,我们将接下持续使用到它。

建筑抽象

STEP 08

回到我们的抽象艺术的文档,把三个同心圆肖像图层集合成组,给这个组增加一个蒙版,利用上一步做成的画笔在这个蒙版上点击创作。这里的目的是要将左同心圆的左边部分做一部分隐藏处理。

STEP 09

增加一个矩形,填充为深色,具体颜色可以是从人像图片中吸取的深色。这个做法最能做到整体的色彩和谐。为矩形增加蒙版,在蒙版上运用自制抽象画笔来创作出一种类似建筑一样的抽象造型。

自然抽象

展开阅读全文

3DSMAX怎么制作抽象热水器 3DSMAX制作抽象热水器方法

全文共 765 字

+ 加入清单

这篇教程教朋友们用3DSMAX制作一个抽象热水器机器方法,制作过程难度中等。制作的机器人是一个抽象的热水器机器人,朋友们一起学习这篇教程。先看看最终的效果图:

具体的制作步骤如下:

设定与模型:我开始设计,在纸上画了几何图形来设计我想要的机器人。小时候我一直想要一个可以帮助我工作的机器人,所以我决定做一个弓着腰工作的机器人,他像是个驼背。腰部我用了一个球体,头部是一个半球体,大致设计了一个机构,然后我一步一步的进行细节的深入。(图02)

图02

然后我把图形转换成可编辑多边形,然后开始进行模型的制作。 (图03、04)

图03

图04

大体模型建立完毕后,我开始进行一些细部零件的制作。(图05、06)

图05

图06

接下来我制作脚的部分,在这里你可以看到这个过程。(图07、图08)

图07

图08

完成了这个工人的模型部分:(图09)

图09

材质部分:我截了一张模型的模型的图,导入到Photoshop进行图层的模式选用不同的颜色进行尝试,尝试不同的颜色,我想设计的是是一个旧热水器式的机器人,所以我决定选用橙色和奶色。 (图10、图11)

图10

图11

这是我的材质图:(图12)

图12

然后我添加了一些像泥土的细节。(图13)

图13

灯光部分:我使用一个照明灯和标准Vray灯光进行组合。你可以通过下面的图看到各个角度与距离。(图14)

图14

渲染部分:这里是我的渲染结果:(图15、图16)

图15

图16

后期制作:这是我在Photoshop里设计的纹理和效果。(图17、图18)

图17

图18

在加入背景的时候,我加入了一些蒸汽,为了增加气氛,所以我使用了Photoshop的笔刷和高斯模糊滤镜。最后整体效果还不错。(图19)

图19

最终效果:

教程结束,以上就是3DSMAX制作一个抽象的热水器机器方法介绍,大家觉得怎么样,喜欢的朋友可以跟着教程来学习吧!

展开阅读全文

一文读懂广义经济抽象

全文共 2353 字

+ 加入清单

在最近被Coinbase收购的Astro Wallet中,我们花费了过去两年内大部分时间来研究各种形式的经济抽象。我们希望与更多的区块链从业者分享我们的发现,希望它可以作为解决当今去中心化应用所面临的许多UX问题的指南。

尽管它不是一个新概念,但以前只有一小部分经济抽象用例在实践上是可行的。在本文中,我们将讨论如何实现针对于经济抽象较为普遍的实施办法。定义

我们已经看到了该术语较为宽泛的用法,因此,我们首先要给出一个明确的定义。

经济抽象——能够以原子的方式,用该区块链上的任意资产支付任何区块链的交易费用和因此产生的后续操作的能力。

让我们举几个例子,以进一步说明该定义:

用户想转账USDC,但没有ETH来支付交易费用。

用户想在0x v3中继器上购买CryptoKitty,其中继器要收取ZRX费用,而卖方要DAI,但用户只有USDC。组成部分

实际上,在大多数区块链上,经济抽象分为两个部分:费用抽象和代币抽象。如果我们能够同时启用这两种功能,那么我们将拥有完整的经济抽象。

费用抽象(fee abstraction)—— 能够以原子方式,用区块链上的任何资产来支付区块链交易费的能力。

协议通常必须具有特定的基础代币(如Ether),以确保其网络的安全性。某些协议接受任何形式的代币以作为交易费,从而实现了费用抽象,但是这不适用于大多数协议。在我们实现的部分中,我们将讨论如何在以太坊等协议上构建费用抽象。

代币抽象(token abstraction)—— 能够以原子方式,用区块链上的任何资产支付因区块链交易产生的后续操作的能力。

一旦执行了交易,后续操作可能会涉及花费任何数量的资产,例如用USDC购买CryptoKitty或在Compound上借贷DAI。借助代币抽象,我们将不仅限于支付特定的代币,而可以支付区块链上的任何资产。具体实施

要实现费用和代币抽象,我们需要两个核心的区块链功能:费用委托(fee delegation)和多操作交易(multi-op transaction)。大多数区块链都没有上述两个原生功能(以太坊都没有),因此需要额外的构造来实现我们的先决条件。在我们的构建中,我们将主要关注以太坊,但这适用于大多数智能合约平台。基本构建块

在以太坊上启用这些核心功能的关键是智能合约钱包的使用。这些功能在传统地址上不存在,但是通过智能合约,我们可以添加其他逻辑以启用新的核心功能。

费用委托(fee delegation)—— 支付交易费用时,指定其他付款人而不是发送者的能力。

如今,大多数智能合约钱包都通过使用Gas中继器来使费用委托更加容易。用户可以直接签署一条消息以进行中继(打包成交易并代表他们发送),而不是直接向他们的智能合约钱包发送交易以支付自己的交易费用。由于用户的实际帐户是智能合约,因此两个入口点都是有效的,只需钱包可以验证调用即可。

多操作交易(multi-op operation transactions)—— 将多个原子函数调用打包到一个交易事务中的能力。

与费用委托不同,多操作交易尚未得到广泛利用。此功能对于促进单个原子事务中的多个操作来说是必需的。Wrapper contract在一定程度上已被用来解决此问题,但是它们隐藏了诸如msg.sender之类的元数据,从而使它们无法用作通用解决方案。幸运的是,此功能非常容易包含在智能合约钱包中。但是,到目前为止,Dapper是唯一支持此功能的智能合约钱包。实现费用抽象

利用多操作交易,我们不但可以构建消息传递协议,还可以构建标准化gas 中继器,以实现费用抽象。在这里,我们提供了一个简单的示例协议,并可以将其进一步扩展以提供其他的钱包功能。

步骤0:客户钱包想发送包含操作[1…n]的交易。

步骤1:客户钱包将其要发送的交易以及其要支付交易费用的资产种类通知gas中继器。

步骤2:中继器以签名报价作为响应,该报价中指定了该资产报价的价格,以中继所请求的交易。

步骤3:客户钱包附加一项额外操作,将该资产的指定值转移到中继器。

步骤4:带有操作[1…n + 1]的已完成交易与签名报价一起发送到中继器。

步骤5:中继器验证交易并报价,然后将交易发送到区块链。

此功能还为客户钱包提供了向gas中继器请求报价的机会,仅选择将已完成的交易发送给报价最低的交易者。实现代币抽象

同样,在多操作交易的支持下,代币抽象则较为容易实现,其关键复杂点在于交易事务分析。客户钱包需要能够分析潜在的交易事务,以查看在执行交易操作时将花费(以及收到)哪些资产以及这些资产中的多少。

在Astro中,我们构建了一个可以运行此分析的自适应以太坊节点,但是由于这主要是工程挑战而不是算法挑战,因此我们将其作为习题留给读者。

一旦我们能够确定操作集的必需资产和最终资产,钱包就可以轻松地与任意数量的DEX接触,以构建与用户基础资产之间的一组交换。像0x API这样的聚合器非常适合收集这些必需的交换,但是钱包还可以使用更简单但滑移率较低的解决方案,例如Uniswap。通过这组交换,钱包可以通过在用户操作之前和之后,分别附加所需资产和所得资产的交换操作,来构造最终交易。经济抽象

现在,我们已经实现了费用和代币的抽象,我们可以将它们结合起来以实现完整的经济抽象。

我们还可以结合其他类似即时批准的简洁功能,因此我们不需要单独的交易即可批准诸如0x和Uniswap之类的协议来花费我们的资产。这也提高了用户安全性,因为我们只需要批准交易所需的内容而不是最大金额。

通过上图我们就可以说明引言中的那个相当复杂的例子。如我们所见,用户仅用USDC就能够支付0x协议的ETH费用,0x中继器的ZRX费用,CryptoKitty卖方的DAI要价以及用于传输交易的gas中继器。

展开阅读全文

一文了解账户抽象化EIP-2938:智能合约钱包为什么有这项需求?

全文共 8366 字

+ 加入清单

以太坊有两种类型的账户:外部账户(Externally Owned Account, EOA)和合约账户(Contract Account, CA)。前者由用户私钥控制,而后者由存储在智能合约账户(有时也被称为智能钱包)内的合约代码控制。外部账户的权限要大于合约账户,因为只有外部账户可以通过支付 gas 启动交易的执行过程。账户抽象化(Account Abstraction, AA)则是一个可以让合约账户成为和外部账户一样的 “顶层” 账户的提案,实现了账户抽象化之后,合约账户也可以支付交易费和执行交易。

之所以提出账户抽象化,是想要在钱包、交易混淆器(mixer)、ÐApp 和 DeFi 等各种应用场景下,显著改善用户与以太坊链的交互体验。账户抽象化方案要为以太坊提供一个基础功能层,来确定何时支付,谁来支付以及怎样支付 gas。

以 Status Messenger 应用为例,其将隐私信使服务与以太坊钱包和 Web3 浏览器集成在一起。目前,Status 钱包仍然是外部账户钱包,因此其不能像智能合约钱包那样支持丰富的用户体验,比如多签安全、基于社交的钱包恢复(social recovery)、支付限额、地址黑/白名单以及无需 gas 费用的元交易。(之所以没有采用智能合约钱包,是因为)智能合约钱包的用户体验受累于 gas 价格波动,即使通过第三方的中继者也无法有效解决这个问题。账户抽象化旨在解决这个问题。

在本文中,我们先探讨智能合约钱包对账户抽象化的需求。然后描述协议的变更及其对节点的影响,借此深入到账户抽象化的关键部分。最后,我们讨论一些关于扩展功能的提案,并以阐释 Status 项目的计划路线图作为本文的总结,因为该项目要与以太坊配合因而势必受到账户抽象化的影响。

历史与动机

账户抽象化这个概念是在撰写于 2017 年的 EIP-86 里首次提出的,其目的是实现 “交易来源和签名的抽象”。不过其动机和想法可以追溯到 2016 年年初 vitalik 提交的一个 issue, 文中建议 “与其将 ECDSA 签名算法和默认的 nonce 机制写死在协议内作为 ‘标准’ 的账户安全机制,不如初步建立一个(统一的)账户模型,在未来把所有的账户都变成合约,让合约可以支付 gas,让用户可以自由定义自己的安全模型。”

要实现最初的提议非常有挑战,因为不仅要大幅修改协议,还要满足系统的安全保证。最近,Vitalik 等人提出了 EIP-2938 草案,该草案概述了一个更简单的实现。这个实现对 协议/共识 的改动最小,并且通过设置节点的内存池规则来满足所需的安全保证。Vitalik 的以太坊工程组 Meetup 演讲和 Sam Wilson 与 Ansgar Dietrichs(EIP 的另外 2 位作者)的ETH 线上演讲(以及附带的两篇文章:1 & 2)都对这个主题做了非常棒的介绍。本文会着重介绍这些资料的关键内容。

动机:账户抽象化背后的动机很简单,但会带来根本性的改变:当前,以太坊交易具备功能可编程性(通过调用智能合约实现),但是交易的验证方式却是固定的。只有持有有效的 ECDSA 签名、有效的 nonce 值以及足够的账户余额,一笔交易才算有效。账户抽象化引入了一种新的交易类型 —— 抽象账户交易(AA Transaction)。这种交易总是由一个特殊地址产生,协议不会检查其签名,nonce 和余额。通过引入这种交易,账户抽象化实现了从固定验证方式到可编程验证方式的转变。抽象账户交易的有效性由其 target 字段指定的智能合约验证,通过验证之后,合约可以自行为该交易支付手续费。

那么,为什么账户抽象化这么有用呢?我们将用以太坊钱包为例,阐述它会带来哪些好处。

智能合约钱包:如今大多数以太坊钱包都是外部账户钱包,它们的安全性由助记词(seed phrase)生成的私钥保护。(一串遵循 BIP-39 标准的助记词由 12-24 个单词依序拼成,这些单词是从 2048 个单词中随机选择的。助记词为 PBKDF2 函数提供所需的信息熵,以生成一串二进制种子。接着,基于 BIP-32 标准的钱包使用该种子生成非对称密钥对。)为了以后能在其他钱包里恢复密钥,用户应当安全妥善地保管助记词。然而,这种钱包很容易因为私钥被盗或者助记词丢失导致用户的资产遭受损失。

(顾名思义)智能合约钱包是通过智能合约在链上实现的。这种钱包能够提供可编程的风险迁移和友好的用户体验,比如多签安全、基于社交或时间的钱包恢复、转账金额限制、地址黑白名单、无需 gas 费用的元交易和批量交易。

虽然智能合约面临因代码质量差而带来的安全风险,但是这种风险可以通过钱包提供方的安全审计来减轻。而外部账户钱包的风险完全由用户自己承担,用户无法获得智能合约那样的可编程的安全保障,用户必须自己保管好助记词。

当前可用的智能合约钱包有 Argent、Authereum、Dapper、Dharma、Gnos is Safe、Monolith 和 MYKEY。从下图可以看到,这类钱包的使用率看起来在增加。

Argent 通过守护者(Guardian)的概念实现了无需种子的基于社交的钱包恢复。守护者是用户信任的人或设备,可以帮助用户恢复钱包。Argent 还要实现类似银行的安全性(提供每日交易限额、账户锁定和可信联系人等功能)与类似 Venmo (译者注:Venmo 是 PayPal 旗下的一个移动支付服务)的可用性(用 ENS(译者注:Ethereum Name Servic,ENS 是一个可读的、去中心化且安全的域名系统)取代地址,支持元交易)。

Gnosis Safe 是一款多签智能合约钱包,专注于团队资金管理,任何一笔交易都要得到团队中最低人数(n 个成员中的至少 m 个)的批准才能发生。它还可以通过元交易实现无需 gas 的签名。

所有这些高级钱包功能都要用到灵活的智能合约。钱包用户要么通过外部账户发送交易,支付 gas 费以调用钱包合约,要么依赖钱包提供方支持元交易功能,借由钱包提供方的中继器或者第三方中继网络如 Gas Station Network 来使用钱包。前者通常是通过了 KYC 认证的用户依靠中心化交易所购买ETH(以支付 gas 费);后者将用户的负担转移到中继器上,由钱包提供方或用户在链上或链下补偿中继器,从而提高用户体验。

然而,基于中继器的架构有三个主要缺点:(1)他们可能会面临中心化的诟病,引起交易审查的担忧;(2)由于中继器发出的交易需要支付额外 21000 单位的基础 gas 费,为了获得利润其必须收取更高的费用以覆盖这部分成本,这就导致了技术和经济上的低效;(3)对中继专用协议的使用,迫使应用不得不依赖非以太坊的基础设施,而较小的用户群无法支撑这些设施提供稳定可靠的服务。

账户抽象化将使智能合约能够接受用户的无需 gas 的元交易,并且无需依赖中继网络就能为其支付 gas 费。因此,这种底层能力在不牺牲去中心化的情况下,能够极大改善这些智能合约钱包的用户体验。

Tornodo Cash:另一个(将受益于账户抽象化的)相关应用是交易混淆器,例如 tornado.cash。Tornado 使用智能合约切断地址之间的链上关联以提升交易的隐私性,该合约允许用户存入 ETH 后通过另一个地址提款。用户在存款时提供一个秘密值的哈希,随后在提款时提供 zkSnark 证明。该证明可以在不泄露秘密值和存款信息的情况下,证明其知道这个秘密值。这样就把存款和提款脱钩了。

但是在提款时有一个鸡生蛋蛋生鸡的问题。为了在新生成的地址上执行提款交易,用户需要给该地址存入一些 ETH 以支付 gas 费。但这些 ETH 的来源(通常是一家交易所)本身又会破坏使用 Tornado 所带来的隐私性。首选的替代方案是再次使用中继网络,而这样做有上述的那些缺点。

账户抽象化就可以解决这个问题,Tornado 合约可以接受用户的提款抽象账户交易,验证 zkSnark,(从存款里)扣除 gas 费,然后把剩余的资金转给提款地址。

账户抽象化

在 EIP-2938 中提出的账户抽象化,接纳合约作为顶层账户,使之可以支付交易费以及启动交易的执行过程。实现账户抽象化需要变更协议以增加新的抽象账户交易类型、修改内存池规则以及引入扩展功能以支持高级用法。抽象账户交易需要增加两个新的操作码:NONCE和PAYGAS。账户类型仍然保持现有的两种(外部账户和合约账户),所有的变更都向后兼容以支持当前的交易、智能合约和协议。

账户抽象化应用可以分成两类:1) 单租户应用,如智能合约钱包,其会为每个用户创建一个新合约;2) 多租户应用,例如 tornado.cash 或 Uniswap,多个用户与同一组智能合约交互。

目前还不能支持多租户应用,这需要更多的研究工作,以期未来早日实现。所以本文将重点介绍单租户的账户抽象化。

协议变更

对协议唯一的变更就是引入了一种新的交易类型,以及相关的两个操作码NONCE和PAYGAS。

抽象账户交易:协议引入了一种新的交易类型:AA_TX_TYPE。它的二进制数据 (payload) 会被解析为RLP([nonce, target, data]),而不是现有交易的

RLP([nonce, gas_price, gas_limit, to, value, data, v, r, s])。

Nonce 检查和现有交易类似,需满足

tx.nonce == tx.target.nonce。

如果检查失败,则交易无效,如果通过检查,则tx.target.nonce将会递增,交易继续进行。

抽象账户交易的基础 gas 消耗量将从 21000 降到 15000(以反映移除了内置的 ECDSA 签名所节省的成本)。此外,抽象账户交易没有内置的 gas 限额。当交易执行时,gas 限额只需设定为当前 block 还剩余的 gas 限额即可。

NONCE opcode:NONCE操作码 (0x48) 推送被调用者 —— 即抽象账户交易的 target 字段所指定的合约 —— 的 nonce 值到 EVM 的栈上。借此,nonce 值被暴露给了 EVM, 因而抽象账户合约可以将交易的任何字段(包括 nonce)作为验签逻辑的一部分。

PAYGAS opcode:PAYGAS操作码 (0x49) 从栈上弹出 2 个参数:(栈顶)version_number,(次栈顶)memory_start。

Version_number允许未来通过新的实现变更操作码的语义。目前,操作码的语义如下:

检查version_number == 0(否则抛出异常)

读取gas_price = bytes_to_int(vm.memory[memory_start: memory_start + 32])

读取gas_limit = bytes_to_int(vm.memory[memory_start + 32: memory_start + 64])

检查contract.balance >= gas_price * gas_limit(否则抛出异常)

检查globals.transaction_fee_paid == False(否则抛出异常)

检查AA execution frame == top-level frame,也就是若当前 EVM 执行退出或回退,整个交易的 EVM 执行就暂停了(否则抛出异常)

设置contract.balance -= gas_price * gas_limit

设置globals.transaction_fee_paid = True

设置globals.gas_price = gas_price,globals.gas_limit = gas_limit

设置当前的执行上下文的remaining_gas = gas_limit - 已经消耗的 gas

在执行抽象账户交易的最后,(globals.limit - remaining_gas) * globals.gas_price的费用将转给矿工,remaining_gas * globals.gas_price的金额则退还给抽象账户合约。

PAYGAS操作码充当 EVM 执行过程中的检查点。任何回退都只退回到上一个检查点,此时合约收不到退款,globals.gas_limit * globals.gas_price的金额全都转给矿工。

这个新的交易类型和这两种新的操作码构成了 协议/共识 级别的全部变更,它们的语义相对直观,易于理解。

内存池规则

“内存池是指以太坊节点内部的,存储在内存里的数据结构,其中存储了用于挖矿的候选交易。Geth 称之为 ‘交易池(transaction pool)’;Parity 称之为 ‘交易队列(transaction queue)’。不管叫什么,它都是一个存储将被区块包含的交易的数据池。我们可以把它看做是待打包区块的 “候车厅”。

抽象账户交易的可编程验证方式引入了更多的复杂性。抽象账户交易并不预付 gas 费,而是依靠target字段指定的抽象账户合约(通过PAYGAS操作码)来支付 gas 费。理论上,抽象账户交易的处理分两个阶段:较短的验证阶段(在执行PAYGAS操作码之前)和较长的执行阶段(在执行PAYGAS操作码之后)。如果验证阶段失败(或抛出异常),会导致交易无效(就像签名无效的非抽象账户交易一样),该交易便不会被区块包含,因而矿工也就拿不到交易费了

因此,矿工和节点需要一个可预测的机制,以避免待处理的抽象账户交易的有效性依赖内存池中的其他待处理交易。否则,一笔交易执行失败可能会导致许多甚至全部的抽象账户交易无效,以此可以构造出拒绝服务攻击。为了避免这种情况发生,我们建议内存池对抽象账户交易执行两条规则(由矿工和节点执行,但不需要修改协议本身)。

操作码限制

为了防止抽象账户交易的有效性取决于抽象账户合约以外的任何状态,在验证阶段(即在执行 PAYGAS 操作码之前)以下操作码被视为无效:执行环境操作码

(BLOCKHASH, COINBASE, TIMESTAMP, NUMBER, DIFFICULTY, GASLIMIT)、

BALANCE(对任何账户的,包括target合约地址)、除了对target合约或预编译合约之外的任何外部调用/创建操作码

(CALL, CALLCODE, STATICCALL, CREATE, CREATE2)、

对除了target合约之外的任何外部状态的读取操作码

(EXTCODESIZE, EXTCODEHASH, ETXCODECOPY, DELEGATECALL)。

如果有抽象账户交易的 target 字段所指向的抽象账户合约违反了这个操作码限制规则,节点就要丢弃这个交易。如此,只要抽象合约的状态不发生变化,内存池中有效的抽象账户交易就将继续有效。

字节码前缀限制

如果非抽象账户交易可以影响抽象账户合约的状态,那么其就可以影响内存池中的抽象账户交易的有效性。为了防止这种情况发生,抽象账户交易应当只接受字节码前缀为AA_PREFIX的 target 合约。AA_PREFIX实现了对msg.sender的检查,确保其是特殊的ENTRY_POINT地址。这有效地防止了非抽象账户交易与抽象账户交易发生交互。

节点如果检查到抽象账户交易指定的合约没有这个AA_PREFIX作为字节码前缀(即不是抽象合约),就应该删除这笔交易。

这两条对抽象账户合约的限制确保了:(1)只有抽象账户合约的内部状态可以影响抽象账户交易的验证逻辑;(2)只有以同一个抽象账户合约为 target 的抽象账户交易可以修改该合约的状态。

因此,只有区块包含了以同一个抽象账户合约为 target 的另一笔抽象账户交易,才有可能使一个待处理的抽象账户交易无效。不过,鉴于这不是协议/共识层的变更,矿工在打包交易时可以随意违反这些规则。

扩展

上述协议变更和内存池规则足以安全地实现诸如智能合约钱包这样的单租户应用。其他高级用法则需要放宽上述规则或者需要实现多租户应用,这就要账户抽象化支持以下形式的扩展:

SET_INDESTRUCTIBLE操作码,它会禁用SELFDESTRUCT,并允许抽象账户合约在验证阶段通过DELEGATECALL安全地调用库函数。

S_STATIC操作码,如果当前的上下文是静态的则返回 true,并允许非抽象账户交易的调用者绕过之前的字节码前缀限制,安全地从抽象账户合约里读取数据。

RESERVE_GAS操作码,当一笔非抽象账户交易试图对一个抽象账户合约写入状态时,设置一个 gas 消耗的下限。这样做是为了强制攻击者在试图让内存池的抽象账户交易无效时至少要消耗一定的 gas,以此抑制其攻击动机。

还有一些其他的扩展,例如存储多笔待处理交易(译者注:内存池存储同一地址的多笔待处理抽象账户交易)、缓存验证结果、验证过程的动态 gas 限制和担保交易等,这些都是为了支持多租户应用和零知识证明。这些内容不在本文的讨论范围内。

下一步

目前,关于账户抽象化的 EIP-2938 还只是一个草案,正在以太坊研究论坛中讨论。下一步是考虑将这个 EIP 纳入即将到来的硬分叉中。EIP 的作者显然瞄着 Berlin (Berlin 暂时定于 2021 年年初的某个时间)之后的硬分叉,具体的时间表还不确定。所以,对于 EIP-2938 来说,现在还处于早期阶段。

此外,也不清楚是否有必要在以太坊的 Layer 1 (L1) 加入 EIP-2938。鉴于 Layer 2 (L2) 方案的灵活性(如我们之前的文章所述),我们也可以在特定的 L2 上实现账户抽象化,这样就不需要升级整个 L1 了。不过,在 L1 上统一支持账户抽象化要比在不同的 L2 上各自实现账户抽象化好。因此,在哪里实现,怎样实现账户抽象化还有待观察。

“账户抽象化在某种程度上不那么重要,因为无论 L1 是否支持,它都可以在 L2 上实现。” —— Vitalik 在谈及基础层的升级需求时表达了这个观点(这在他写的那篇以 rollup 为中心的以太坊路线图的帖子中提到了)。

Status:Status 钱包目前是一个外部账户钱包,它的独门绝技是将聊天支付和 Keycard (译者注:一种硬件钱包)集成到一个隐私信使服务中。目前其正在考虑加入一些智能合约钱包的特性,如多签和基于社交的钱包恢复。如前所述,支持 EIP-2938 有助于消除对中心化和低效的中继架构的依赖。

Status 也在评估 L2 解决方案,正如我们之前的文章里说的,这样做既可以在钱包里支持多链,也可以为多种用例提供所需要的扩展。例如,Keycard 正在探索一种支付网络,其所需的信用卡级别的可扩展性和近乎即时的终局性是目前以太坊网络无法满足的。此外,还有许多其他计划,如推荐计划、SNT reaction、Tribute-to-Talk 和 ENS 域名。所有这些计划都适合在 L2 上实现,因为这在部署上可行,而且能够提供还不错的用户体验。如果一个可行的 L2 方案实现了账户抽象化,那么在该 L2 上的项目都能享受账户抽象化的好处,而不必依赖 L1。

总结

以太坊协议的一个根本问题是,只有外部账户(EOS(可以支付 gas 费和启动交易执行过程,而合约账户(CA(做不到。账户抽象化(AA(是一个旨在改变这种区别的提案,允许具有特定构造的合约账户可以检查新增的一类交易 —— 抽象账户交易的有效性,并代为支付 gas 费,从而在不需要外部账户的前提下有效地启动交易的执行过程。

账户抽象化能够在不依赖中心化和低效的中继架构的情况下,显著改善钱包、交易混淆器、ÐApps 和 DeFi 的用户体验。通过引入一种新的交易类型,两种操作码以及两条内存池规则,账户抽象化能够安全地支持基本的单租户场景,如智能合约钱包。如果要支持更高级的多租户应用,如 Tornodo Cash,则需要对协议和节点规则做更多的扩展。

本文阐述了智能合约钱包对账户抽象化的需求。通过描述协议的变更和对节点的影响来强调账户抽象化的关键部分。我们还谈到了一些针对高级用法的扩展提案,最后通过介绍 Status 项目在以太坊上的路线图和优先级让读者对账户抽象化有一个比较清楚的定位。

减少 Web3 的摩擦及改善用户体验是这个生态里所有项目的首要任务。账户抽象化,最终一定会以某种形式在未来发挥重要的作用。

展开阅读全文

干货 | 账户抽象的动机、历史和分析

全文共 7390 字

+ 加入清单

概述

账户抽象[[Account Abstraction]] 是以太坊上的一种待实现的技术方案,按现阶段设计,在实现账户抽象之后,一个智能合约账户也可以主动发起交易,而无需依赖 “元交易” 的机制。

背景

以太坊的账户有两种类型,一种是外部账户,另一种是合约账户。外部地址是由用户的公钥经过哈希运算后取的后 20 个字节,形为 0x76D836358E7A2BB0F26c32Ce61Dc8DD540b02F7D 。目前的以太坊的事务类型只有一种,必须由外部地址发起,合约地址无法主动发起事务。因此,任何合约自身状态的改变,必须依赖于一个外部地址发起的事务,无论是一个多重签名账户,还是混币器,或是任何智能合约的配置变更,都需要由至少一个外部账户触发。这样的设计让以下两件事情无法完成。

1. 无需以太的主动事务

由于事务必须由外部账户发送并支付费用,而该费用是用以太(ETH)为单位结算的,因此该外部地址必须持有以太。当然,这种说法并不严谨,当 gasprice 为 0 时,事务无需支付手续费。可这种情况非常极端(见 [1]) ,对于普通用户来说,这样的事务可能永远无法入块。

2. 非secp256k1的原生验证方式

由于事务必须由外部账户发起,因此每笔事务的合法性检查就是在验证事务是否提供了该账户对应的合法的 secp256k1 签名。而如果要在验证中引入复杂逻辑(例如多重签名或社交恢复)或是采用不同的验证算法(例如 Eddsa、BLS、secp256r1 签名算法,使用这些签名算法是因为它们有特别的特性,或是对零知识证明友好,或是方便签名聚合减少带宽开销,或是与现有的硬件验证器兼容),则必须在智能合约层面实现。这也同时意味着,这种验证仍要由至少一个外部账户发起,并通过以太坊的 secp256k1 签名验证。

上述两条约束让普通用户很难使用以太坊。首先,无论使用以太坊上的什么应用,用户都必须持有以太(并承担以太价格波动的风险)。其次,用户需要处理复杂的费用逻辑,gas price、gas limit、事务阻塞,这些概念对用户来说过于复杂。许多区块链钱包或应用试图通过产品优化提高用户体验,但效果甚微。

如何解决上述两个问题呢?

核心思路在于将 “验证所有权” 的操作由共识层下放到合约层,即不去检查事务的发送者是否与资产所有人一致,而是检查其是否提供了合法的凭据。具体的做法为:用户对事务内容进行签名,并将签名交由一个第三方操作上链,这个第三方我们在接下来的文章中用 “运营商(operator)” 来指代。这种事务被称为 “元交易”。根据设计理念的不同,元交易方案大致分为两类:

1. 以账户为中心——智能钱包

以账户为中心的方案的目标是为用户创建一个基于智能合约管理的账户,用户可以使用该账户与区块链上的任意合约交互。智能钱包的理念由来已久,但在近一年来有了长足的进展。根据「智能钱包趋势」的统计(注:作者为本人,特此声明),目前「智能钱包」的运营商超过 10 家,总用户数超过 14 万。其中大部分智能钱包采用了为用户代付链上手续费的运营策略,再通过其它方式向用户收取费用。

以账户为中心的方案本质上是一套区块链账户系统,通用性强,且可以提供包括账户恢复、大额审批、转账白名单等附加特性。智能钱包的运营者协助用户创建、管理区块链上的可编程身份,并提供事务上链服务。一般来说,智能钱包会为用户支付链上的 gas 费,同时通过中心化计费系统向用户收取费用。这套模式和传统世界里的账户服务很像,例如运营商支付基站、光纤等费用,而用户只要充值话费就可以使用通信服务,而无需关心底层复杂的逻辑。

智能钱包也有其掣肘。一是安全问题,二是费用问题。

安全:如果账户合约存在漏洞,那么所有用户的资产都会遭受风险。专业的代码编写、安全审计和形式化验证,都只能减少风险发生的可能,而不能保证它不会发生 —— Argent 已经发生过。

费用:智能钱包的账户创建需要费用,而转账和任何调用任何合约都会比外部地址花费更多费用。这导致智能钱包的用户需要支付更高的事务费用,这影响了他们的使用体验

2. 以资产为中心 —— 无气通证

无气通证也存在其问题。从目前的使用情况来看,极少有人使用这种特性(需要数据支持)。在「智能钱包,不止元交易」一文中,我分析了可能的原因,其中之一在于没有办法建立有效的计费系统。

以资产为中心的方案提高了资产的可用性。不同于智能钱包需要创建智能合约账户,无气通证可以支持外部账户在不使用以太的情况下进行转账,反而是智能合约账户需要兼容更多规范(例如 EIP-2126,让合约可以识别不同类型的签名格式),否则无法让无气通证的合约验证所有权

以资产为中心的方案的目标是创建允许由第三方支付费用的资产,实现 “无需 gas 的通证”。例如,DAI、USDC 都可以允许任意外部地址使用元交易的方式发送资产。这些通证协议都使用 EIP-712 协议验证拥有者的合法性。

账户抽象的发展史

根据 Matt Garnett 整理的账户抽象发展历史[2],从以太坊 2015 年上线起,账户抽象的讨论没有停止。本文将按照时间顺序,对账户抽象相关的EIP进行简要介绍。需要说明的是,该历史漏掉了 EIP-208,我做了相应补充。

EIP-101:货币与密码学抽象

[[November 15th, 2015]]

在这个 EIP [3] 中,Vitalik 讨论了对 Serenity 中的账户体系的设计。这个方案的主要思想是,每个账户都拥有自己的 “代码”,也即逻辑部分。由于该方案改动过大,与当前事务的兼容性不好,会造成许多安全隐患,该方案被搁置到分片之后。

EIP-86:事务来源和签名抽象

[[February 10th, 2017]]

经过漫长的讨论,Vitalik 提出了 EIP-86。EIP-86 是为账户抽象做技术准备,它定义了一种新的账户类型,允许用户创建基于智能合约的账户,该账户是一个代理合约(forwarding contract),存储 Ether,在入口点检查事务的签名,并将验证合法的事务转发到指定的地址,并支付相应的费用。这种机制对多签钱包、环签名混币、自定义的密码算法(例如 ed25519)等场景的实现有更多帮助。

对 EIP-86 的讨论展开了很久,值得说明的是,Vitalik 丰富了协议细节,提出了 EIP-208。EIP-86/208 计划于 Metropolis 阶段升级,但在第 19 次核心开发者会议 [4] 上,开发者提出了很多问题,并决定在 Metropolis 中暂缓引入,主要理由如下。

账户抽象带来新类型的事务,与传统事务必须有一个 EOA 作为发送者相比,这些事务没有发送者。这种事务破坏了事务哈希的唯一性,尽管这不会对 EVM 的执行造成影响,但是所有基于 “唯一性” 假设的外部操作都会收到影响。例如,所有通过事务哈希来定位事务的 RPC 接口。

此外,账户抽象的 “无气支付” 是一个优化,但是必要性不足。因为其功能可以通过 “代理合约” 实现,唯一的问题是其开销会比原生实现要大一些。

矿工的挖矿策略会受到极大影响,在被广泛接纳前,这些新类型的事务可能无法被很快广播。

这种新类型的事务仍然保留了 nonce、gasprice、value 字段,且被设为 0。这非常不优雅,希望未来用新的事务类型解决,而不是引入技术债。

EIP-859:主网上的账户抽象

[[January 30th, 2018]]

与前两个 EIP 不同,EIP-859 并没有形成确定性的草案,而是始终在讨论过程中,没有定稿。该提案希望账户合约有一个相对规范的实现,即(1)检查签名(2)支付手续费(3)调用目的账户。

如果 EIP-859 实现,可以抽象(1)签名算法(2)更复杂的逻辑,并且不会破坏 “事务哈希唯一” 的特性,但仍然不能允许使用 ERC-20 支付费用。

这个提案在第 34 次和第 40 次核心开发者会议的笔记中被提及。根据会议笔记,第 33 次核心开发者会议上决定搁置该提案,而是聚焦于 Casper。而 Vitalik 在第 34 次会议 [5] 上承认该提案仍不成熟,但 “不管怎样在分片时会实现”。Hudson 指出,君士坦丁堡升级包含的内容太多了,因此不再考虑该提案。第 40 次核心开发者会议上,大家决定永久搁置该提案,无人反对。

EIP-2938:账户抽象

[[September 4th, 2020]]

时间又过了两年,ETH 2.0 的 Phase 0 已经启动,而账户抽象也被重新提上议程。出乎意料的是,该提案建议在 ETH 1.x 上首先实现。

简单来说,账户抽象的目标是让智能合约成为顶级的账户类型,而非受限制的必须由外部账户调用的账户,这样智能合约账户就可以主动发起事务并支付手续费。这个目标与 EIP-86 已经有了很大区别,当时的提案希望彻底消灭外部账户,或者说将所有的外部账户都变成合约账户,而此提案仍然保留了外部账户的存在。

以太坊当前的事务合法性只通过三个参数判断:ECDSA 签名、自增 nonce 和账户余额,因此节点非常容易判断一笔事务的合法性。然而,这势必造成了很多限制。EIP-2938 实现后,以下场景可以主动实现:

(1) 智能钱包使用 ECDSA 之外的算法验证签名;

(2) 智能钱包的其它特性,包括多重签名和社交恢复;

(3) 保护隐私的系统,例如 Tornado.cash;

(4) 提高 DeFi 协议 gas 效率;

(5) 用户使用其它 token,而不是 ETH 支付手续费。

目前,以上用户场景也可以通过间接的方式实现。该提案认为这种方式在技术和经济上都不高效。

EIP-2938 分为单租户和多租户两个阶段,顾名思义,其区别在于账户的拥有者是单个用户还是多个(不特定的)用户。在单租户阶段能满足 (1)、(2) 和 (5) 场景的需求,而只有在多租户阶段 (3) 和 (4) 才能实现。多租户阶段的技术方案仍未成型。有关 EIP-2938 的更多内容,可以参考 Status 发表,以太坊爱好者翻译的文章[6]。

代价是什么?—— 硬币的两面

毫无疑问,假设账户抽象成功部署,可以带来新的功能特性,但也一定有取舍,不可能得到美好的东西,但不付出什么代价。过去五年的讨论给了我们足够的经验,其负面影响甚至由于其复杂性而难以分析。尽管如此,本文将试图系统讨论其潜在收获和代价,以便读者公允地判断。「账户抽象的收获」参考了核心开发者 Peep an EIP 文档[7]。

1. 账户抽象的收获

(1)主动发送事务的智能合约账户。

智能合约账户可以无需 EOA 触发而主动发送事务,减少了对运营商的依赖,且 gas 消耗更少。

(2)提高混币器的隐私性。

现阶段,用户从类似 Tornado.cash 的混币器中提款仍需要依赖一个 EOA 账户发送事务,这个 EOA 账户是暴露隐私的脆弱环节。实现多租户的账户抽象后,任何人提取代币时,均无需额外支付费用,而直接从提款金额中扣除。

(3)使用其它代币支付手续费。

现阶段,用户必须使用 ETH 支付网络的手续费,在账户抽象实现之后,用户可以使用其它 token 支付手续费。但这不意味着在协议层矿工会接受非 ETH 作为手续费,而是通过和 DEX 交互换取 ETH 支付手续费。

(4)减少链上无效套利交易,提高可扩展性。

现阶段,在链上发现套利机会时,可能存在多个套利者同时发起套利交易,而首笔成功的套利事务会让其余事务的套利行为失效,但这些事务仍然会被打包在以太坊中(如果 gasprice 足够,且没有使用相同 nonce 替换该事务),这导致以太坊上存在大量的 “垃圾” 事务。而实现账户抽象之后,由于可以在账户权限验证阶段进行价格判断,那么套利者无需为失败的套利行为付费,链上也不会包含失败的套利事务,可以有效提高链的可扩展性。

2. 账户抽象的代价

(1)加大内存池验证事务有效性的开销

在现阶段,节点收到一笔事务时,很容易判断其有效性,并将其载入内存池。节点只需要判断三件事:签名的有效性、nonce 的合理性(账户当前 nonce 加 1 或合理的数值)、账户的余额,如果其中任意一条不满足,节点可以选择丢弃该事务。非法事务并不会支付手续费,节点是免费 “验证”,由于验证 ECDSA 的签名非常简单,开销极低,目前网络的安全性不会受到挑战。

当引入账户抽象后,判断一笔事务的有效性的难度大了很多,节点需要为无效事务的验证花费更多计算资源,而不能从中收取任何费用。有关 DOS 攻击,参见[8]

(2)加大内存池确保事务有效性的开销

现阶段,一旦节点验证某笔事务的有效性,除非该账户使用相同 nonce 发送新的事务并被打包,否则这笔载入内存池的事务将永远有效,直到被打包进某个区块(也可能因为 gasprice 太低而一直没有打包)。而账户抽象之后,判断事务的有效性的难度提高了,内存池中的多笔事务在被打包前可以同时有效,但由于其有效性可能依赖全局状态,存在其中某一笔事务执行后剩余事务全部失效的可能性。因此,需要建立新的内存池规则,以避免这种情况的出现。

(3)引入新的事务类型、计费方式、挖矿和广播策略

首先,引入了新的事务类型。在 EIP-86/208 的讨论过程中,一度有一种倾向是 “消灭” EOA 账户,或者说把 EOA 账户包裹在一个智能合约账户内,这样链上的基本账户类型和事务类型都只有一种。而在本提案中,EOA 账户得以保留,即存在两种类型的账户——EOA 和 AA,也有两种事务类型。同时,AA 事务调用其它合约时必须加上前缀,以防止 EOA 账户发起对 AA 账户状态的修改,影响事务有效性的判断,这可能会带来兼容性的问题。

其次,计费方式发生了变化。现阶段,矿工无需关心事务的内容,只需要确认事务的发起方的ETH余额大于 gaslimit*gasprice,就可以保证收到手续费。而在账户抽象之后,如何保证矿工可以收到手续费呢?本提案将一笔事务分拆成两个部分——验证阶段和执行阶段,用一个新的操作符 PAYGAS 间隔。在验证阶段,完成对账户权限的验证,在此阶段不允许调用外部数据或操作账户余额。与现阶段的方法一致,验证通过则支付手续费并开始执行事务,即使事务在执行阶段回滚,也仍然会被包含在区块中且支付费用,但验证不通过则丢弃该非法事务。

再者,挖矿和广播策略变得更加复杂。为了保护内存池和矿工的安全,推荐的挖矿策略更加保守。每个账户的待处理事务只保留一个,不再保留更高 nonce 的事务;对验证阶段设置 gas 的容量上限;在 AA 账户发起的事务被打包进入区块之后,需要丢弃掉内存池所有对此账户进行操作的事务。

为了避免前 2 条代价造成的潜在影响,以太坊协议层需要做相应的技术改动。

重新评估「收获」?

要评估账户抽象的必要性,首先不妨来回顾其 “收获”。“收获” 无非分为两种类型——原来不能做的,现在可以做了;比原来做得更好了。

(1)主动发送事务的智能合约账户。

智能钱包可以做到这件事情,此收获属于一种改进。由于事务的有效性依赖于合格的签名(或其它凭证),而非发送事务的 EOA 账户,因此任何 EOA 账户都可以提交事务,不存在信任或可靠性风险。由于无需转发事务,更少的 gas 消耗是一个合理的 “收获”,但能达到整体的最优吗?换句话说,在引入了如此复杂的技术改动之后,针对相同的事务内容,计算机在相同时间内可以处理更多的 AA 事务还是 EOA 事务?

结论:一种需要技术验证的改进。

(2)提高混币器的隐私性。

目前 Tornado.cash 使用运营商的模式,替代用户提交取款的收据。与智能钱包的运营商不同,隐私运营商可能不够稳定和 ,任何人可以替代提交事务,但隐私场景下的运营商可靠性会低于通用场景,可能造成服务不可用。不过,这需要在多租户阶段才能实现,而目前多租户模式的方案的可行性、安全性仍然需要验证。

结论:一种提高服务可用性的改进。但不知道能否上线,何时可以上线。

(3)使用其它代币支付手续费。

现在智能钱包在做类似的事情,例如 Argent、MYKEY 都允许用户使用 DAI 支付手续费,但这一操作并非原子的。使用稳定币等资产通过 DEX 兑换 ETH 支付手续费,乍看解决了原来不能解决的问题,但我想表达的是,真实需求并非是技术完备性,而是使用稳定的货币来对抗不稳定的手续费(ETH 价格波动、gasprice 价格波动、gas 消耗不确定)。使用链上事务直接置换手续费,有一种每次使用手机联网前,先买充值卡充话费的感觉,似乎回到了投币电话的时代。何况这笔事务还有巨大的失败风险,因为链上状态的改变可能影响价格。当然,这并不是说投币电话没有用处。

结论:一种可以实现原子化使用非 ETH 资产支付手续费的改进。但不解决价格波动问题,真实需求存疑,且计费方式效率低下。

(4)减少链上无效套利交易,提高可扩展性。

在研究过程中,关于 “减少链上无效事务可以提高链扩展性”的论述甚至让我怀疑整个账户抽象的动机。在现有的模型下,套利者追求套利机会,但由于策略公开,可能导致不同的套利者竞争,抬高网络费率并引入大量失败的套利事务。然而,套利者更明白这个道理,因此也会评估套利失败的后果,否则就要付出手续费的代价,恰恰是这个成本让系统处在动态博弈中。如果竞争套利的行为不需要付出成本,那么尽管不会出现无效的链上事务,但整个系统却会容纳更多的套利行为,让节点承受更多的无法收费的计算任务,何谈增加系统的可扩展性?

结论:不是改进,更像是为了链上 “干净” 的一种固执。

综上所述,这些声称的改进大多只是对现有实现的 “优化”,且缺少足够的验证,部分 “优化” 甚至经不起推敲。

总结

本文总结了以太坊 “账户抽象” 的背景,“账户抽象” 主要为了解决两个问题,一是无需 Ether 发送事务,二是实现自定义的验证逻辑和算法。为了解决这些问题,以太坊历史上提出了多个提案,本文分析了这些提案的企图和最终未采纳的原因。本文的重点是针对 EIP-2938 这个最新的关于账户抽象的分析,讨论了其 “收获” 和 “代价”。“账户抽象” 可以将一些现阶段需要引入“信任” 才能实现的功能变得更加可靠,例如为混币器提供更好的隐私,或是使用例如稳定币在内的资产支付手续费,但也不可避免地带来技术架构的大改动,其安全性也需要更完备的验证。引用阿剑的一段话“而如果某些技术,既没有增加人们可选的东西,又牺牲了人们实际上选择了的东西,那就没有理由对这些技术怀有信心。”

展开阅读全文