可信存证

电子数据的认定包含3个重要的部分,称为“三性”: 真实性 关联性 合法性 1. 真实性认定 由于电子数据存证的特殊性,其真实性可以从三个不同的层面来认定: 电子证据载体的真实性 电子数据的真实性 电子证据内容的真实性 1.1 电子证据载体的真实性 电子证据载体的真实性,是指存储电子数据的媒介、设备在诉讼过程中保持原始性、同一性、完整性,不存在被伪造、变造、替换、破坏等问题。 主要包括两个方面的要求: 电子证据载体来源的真实性 电子证据载体在诉讼前和诉讼流转过程中的真实性。 具体来说,法官审查电子证据时往往会关注:提交的电子证据是否包括原始存储介质,原始存储介质的收集程序、方式是否符合法律规定和有关规范;如果无法提取原始存储介质,如何确保其他存储介质能够保障电子数据的真实性。 这是对电子证据载体原始性和同一性的审查。 二是电子证据载体在诉讼前和诉讼中流转过程中的真实性。诉讼前和诉讼中,证据会在多个主体(如刑事案件的公、检、法和民事、行政案件中原告、法院、被告)间流转。在此过程中需要考察:电子证据载体在移送、 流转中是否保持同一性,是否符合鉴真的要求;电子证据载体是否保持完整性,没有被改变、破坏等。 区块链技术极大地扩展了电子证据的载体外延,并可以从技术上确保电子证据载体的真实性。具体而言,区块链存证使用分布式存储并附加防篡改校验机制,使电子证据可以脱离原始存储介质而 安全存储,同时无被篡改之虞 区块链技术有效解决了电子证据载体真实性认定的问题。 1.2 电子数据的真实性 电子数据的真实性问题,是指作为电子证据信息在技术层面的存在形式的电子数据是否真实,是否与原始数据保持一致,是否存在被修改、删除、增加等问题。 电子数据的真实性,是区块链存证的真实性评价中的一个关键问题。因为,如前述,区块链技术可以保障电子证据的载体及载体上证据副本的真实性,但载体的真实和副本数据的真实,无法决定电子数据本身的真实性(意思是虽然副本和原件相同,但原件不一定是真实的)。同时,在区块链存证场景下,如果电子证据或其证据指纹(或称校验数据)上链并分布式存储,则证据的真实性已经具有技术保证。 则欲保障电子数据的真实性,则需要确保作为电子证据的数据信息(或其证据指纹)在生成时即同步上链, 或者确保该数据信息在上链前未被篡改。考虑到确保作为电子证据的数据信息在上链前未被更改实际上是一个传统的电子证据鉴定场景,不能发挥区块链技术的优势,故而在区块链存证领域,比较理想的确保电子数据真实性的方案即为作为电子证据的数据信息(或其证据指纹)在生成时即同步上链。 1.3 电子证据内容的真实性 电子证据内容的真实性,是指:(1)在“排除合理怀疑”的证明标准场合,电子证据所包含的信息可以与案件中其他证据所包含的信息能够相互印证,从而准确证明案件事实;(2)在“优势证据”证明标准场合, 电子证据所包含的信息可以证明一定的法律事实,特别是证明当事人的意思表示和法律行为。 电子证据内容的真实性是电子证据真实性的核心问题,不少语境中,电子证据的真实性,往往也是指电子证据内容的真实性。在司法实践中,鉴定意见、证据相互印证是确认电子证据内容真实性的主要方式,有些情况下二者还会同时使用。 附加可信时间戳的上链数据,可以推定为形成于特定时间点,则该数据中的时间信息就具有内容真实性。 同理,通过区块链达成的智能合约,在作为证据使用时可以推定合约内容数据真实,合约内容数据也具有了内容真实性。(意思是如果交易通过智能合约达成,可以保证交易是真实的,那么交易的内容就具有了内容真实性) 2. 关联性认定 证据的关联性,是指证据必须和需要证明的案件事实或其他争议事实具有一定的联系。 区块链在单纯的存证场景应用,技术本身并不增强电子证据的关联性。如果是一类或一系列业务运行在区块链上,因其全流程留痕,可能因为可追溯性使证据的关联更加明确,方便进行关联性认定。 无论如何,上链证据和案件无关的情况不可避免,区块链存证不能确保电子证据具有关联性,而是在部分场景下为电子证据的关联性认定提供参考。(证据链) 3. 合法性认定 证据的合法性认定包括取证主体合法性、证据形式的合法性、取证程序合法性以及证据保存与运用方式合法性四个方面。它是证据认定主体机械式对比法条的过程,其中不掺杂证据认定主体的私人价值评价。因此,与证据的真实性、关联性要求不同,证据的合法性判断不应考虑与案件事实的联系,而与法律规定密切相关。(这就不是区块链要考虑的问题了) 4. 可信时间戳 由于区块链本身上存储的只是哈希值,而非原件,因此在示证的时候如果没有原件与哈希值相对应,存证也将无法达到目的。因此,电子数据存储电子数据原件也是区块链司法存证系统的重要部分。 可信时间戳是将用户的电子数据信息和权威时间源绑定,由国家授时中心提供授时信息,将对电子数据信息和授时信息进行数字 签名生成时间戳。通过可信时间戳可确定电子数据信息生成的精确时间,并防止电子文件被篡改,为电子数据提供可信的时间证明和内容真实性、完整性证明。 可信时间戳是表示电子数据在一个特定时间点已经存在的完整的可验证的数据。 5. 区块链存证系统对电子数据认定的作用 区块链技术对电子数据证据认定的作用,即对电子证据“三性”的影响,首先在于对电子证据真实性的判定所产出的显著影响。此外,对于某些业务类型,诸如证据在链上形成并同步存储的情形,该系统对于证明所存证据的合法性和关联性也具有一定帮助。 具体而言,该系统对于证据认定辅助功能主要通过以下四个层面来实现。 安全架构确保电子数据载体真实性 关键技术提高电子数据真实性 相关技术提高证据认定效率 相关业务和链下治理辅助证据认定 6. 总结 在理想情况下(即电子数据生成时即同步上链):...

August 5, 2021 · 1 min · 李昌

依赖注入:wire包的使用

官方教程,写的很好,我就不多说了 Let’s learn to use Wire by example. The Wire guide provides thorough documentation of the tool’s usage. For readers eager to see Wire applied to a larger server, the guestbook sample in Go Cloud uses Wire to initialize its components. Here we are going to build a small greeter program to understand how to use Wire. The finished product may be found in the same directory as this README....

July 6, 2021 · 9 min · 李昌

堆和栈的区别

1. 栈(stack) 栈用于存储函数(包括主函数)内部使用的变量,是一个先进先出(LIFO)结构,每次声明一个新变量,都会将其推入栈中。当函数运行结束时,栈上上与该函数所有相关的变量(称为一个栈帧)将被释放。栈由CPU自动管理,用户不必关心如何分配和释放内存。栈内存分为栈帧,每次函数调用都会为其分配一个栈帧,在函数返回时释放。 栈的大小通常有限,如果程序试图将过多的信息放入栈中,就会出现栈溢出。 栈的先进后出并不是指栈中的变量是先进后出的,而是指"栈帧"的先进后出,这保证了函数的调用顺序。 栈内存由CPU管理 变量自动分配和释放 栈的大小有限制 当变量创建和销毁时,栈会增长和收缩 2. 堆(heap) 堆是一块大的内存,支持动态分配,由用户负责管理。可以通过malloc方法分配内存,通过free方法回收内存,若内存使用后没有回收,则会导致"内存泄漏",即这块内存无法被其他进程所用。 与栈不同,除物理内存大小的限制,堆的大小没有严格限制。在堆中创建的变量可在程序的任何地方访问(全局变量)。 堆内存由程序员管理 在C中,使用malloc和free来分配和释放堆内存 需要用指针访问堆 3. 考虑以下程序 #include <stdio.h>#include <stdlib.h> int x; int main(void) { int y; char *str; y = 4; printf("stack memory: %d\n", y); str = malloc(100 * sizeof(char)); str[0] = 'm'; printf("heap memory: %c\n", str[0]); free(str); return 0; } 在上面这段程序中,x是一个全局变量,y和str都是局部变量。malloc为str在堆上分配了100个字节的内存,free则释放了分配的这些内存。 参数 堆 堆 数据结构类型 堆栈是线性数据结构。 堆是一个层次数据结构。 访问速度 高速访问 与堆栈相比速度较慢 空间管理 空间由操作系统高效管理,因此内存永远不会变得支离破碎。 堆空间没有有效地使用。当内存块首先分配然后释放时,内存可能会变得支离破碎。 访问 仅限本地变量 它允许您在全球范围内访问变量。 空间大小限制 取决于操作系统的堆栈大小限制。 内存大小没有特定的限制。 调整 变量无法重新缩放 变量可以重新缩放。 内存分配 内存被分配到一个连续块中。 内存以任意随机顺序分配。 分配和交易定位 通过编译器说明自动完成。 它由程序员手动完成。 释放 不需要去分配变量。 需要明确去分配。 成本 少 更多 实现 基于简单阵列、使用动态内存和基于链接列表的 3 种方式可以实现堆栈。 堆可以使用阵列和树木实现。 主要问题 内存不足 内存碎片 参考地区 自动编译时间说明。 足够 灵活性 固定尺寸 调整大小是可能的 访问时间 更快 慢

June 23, 2021 · 1 min · 李昌

5种goroutine池的实现之对比

1. wazsmwazsm/mortar(★74) 简单介绍 创建一个容量为 N 的池, 在池容量未满时, 每塞入一个任务(生产任务), 任务池开启一个 worker (建立协程) 去处理任务(消费任务)。 当任务池容量赛满,每塞入一个任务(生产任务), 任务会被已有的 N 个 worker 抢占执行(消费任务),达到协程限制的功能。但worker创建后不会回收,除非将整个pool撤销。 结构 type Task struct { Handler func(v ...interface{}) // 函数签名 Params []interface{} // 参数 } // Pool task pool type Pool struct { capacity uint64 // 池的容量,自行制定 runningWorkers uint64 // 正在运行的worker status int64 // 池的状态 chTask chan *Task // 任务队列,worker从中获取任务 PanicHandler func(interface{}) // 自定义的PanicHandler,防止因某个goroutine发生panic而导致服务崩溃。 sync.Mutex // 全局锁 } 核心代码...

June 19, 2021 · 13 min · 李昌

十分钟学会区块链合约开发

1. evm虚拟机 交易的执行是区块链节点上的一个重要的功能。是把交易中的智能合约二进制代码取出来,用执行器(Executor)执行。在交易的执行过程中,会对区块链的状态(State)进行修改,形成新区块的状态储存下来(Storage)。执行器在这个过程中,类似于一个黑盒,输入是智能合约代码,输出是状态的改变. 以太坊虚拟机(environment virtual machine,简称EVM),作用是将智能合约代码编译成可在以太坊上执行的机器码,并提供智能合约的运行环境。它是一个对外完全隔离的沙盒环境,在运行期间不能访问网络、文件,即使不同合约之间也有有限的访问权限。以太坊虚拟机提供了面向合约的高级编程语言solidity,这使得开发者可以专注于应用本身,更方便、快捷的开发去中心化应用程序,同时也大大降低了开发难度。 EVM是一种基于栈的虚拟机(区别于基于寄存器的虚拟机),用于执行智能合约,同时EVM是图灵完备的,EVM操作数栈调用深度为1024,EVM机器码长度一个字节,最多可以有256个操作码,目前已经定义了144个操作码,还有100多个操作码可以扩展,每个操作码都根据其弹栈数、压栈数定义了相应的gas消耗数量。泰岳链应用了以太坊EVM机制来实现智能合约,并增加了对国密算法的支持(SM3)。 2. solidity语言 Solidity 是一门面向合约的、为实现智能合约而创建的高级编程语言。这门语言受到了 C++,Python 和 Javascript 语言的影响,设计的目的是能在 以太坊虚拟机(EVM) 上运行。 Solidity 是静态类型语言,支持继承、库和复杂的用户定义类型等特性。 直接看这里:Solidity最新中文文档 3. 使用Ganache与truffle进行合约开发 Ganache ganache可以快速的在本机上启动一条以太坊链,用户可以方便的在上面部署合约,调用合约,完成各种与合约之间的交互。 ganache提供了Windows、Linux以及Mac三种系统的版本,直接到其官网或GitHub页面下载安装即可。 安装完成后,即可以快速部署一条链 使用QUICKSTART模式部署的链只会在本次会话中存在,关闭当前会话或注销当前用户都会导致链的撤销,如果只是写个小demo的话,那么使用这种方式即可。 NEW WORKSPACE则会创建一条持久化的链,不会因会话结束或用户注销而撤销链。 使用QUICKSTART模式启动 ganache会自动创建10个测试账号,每个账号分配了100个原生币,交易需要消耗这些原生币。 在页面的上方,还有其他一些选项卡,可以方便的查看当前区块、交易、事件、日志等。需要注意的是在这些选项卡的下方,还标注了本链的一些信息,如它的端口,网络ID等。 truffle truffle提供了合约开发、测试、部署等一系列工具,通过与Ganache配合可以十分方便的测试你的合约。 安装truffle npm install -g truffle 新建一个truffle项目 mkdir MyContract truffle init truffle会创建如下的目录结构: ├── contracts │ └── Migrations.sol ├── migrations │ └── 1_initial_migration.js ├── test └── truffle-config.js contract目录中存放我们的合约;migrations目录中存放migrate文件,功能类似数据库migrate文件,简单来说,就是让你的应用从一个状态迁移到另一个状态;test目录中存放测试文件(还未创建);truffle-config.js是配置文件,其中配置了链的地址等信息。 根据提示我们来创建一个简单的合约模板: truffle create contract Counter truffle创建了Counter.sol文件,再次查看目录结构: ├── contracts │ ├── Counter....

June 17, 2021 · 3 min · 李昌

WSL2-不输Mac的开发体验(一):WSL2的安装及基本配置

1. WSL的安装 1.1 升级Windows WSL需要高版本的windows,可使用微软官方的易升工具或直接从设置中升级,升级需要一定的时间。 1.2 安装WSL 使用管理员模式打开power shell, 使用如下命令开启WSL功能 dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart 重启你的机器 启用虚拟机功能 以管理员身份打开powershell,使用如下命令: dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart 重新启动电脑 下载Linux内核更新包 适用于 x64 计算机的 WSL2 Linux 内核更新包 运行你下载的更新包。 将WSL2设置为默认版本 以管理员身份打开powershell,使用如下命令: wsl --set-default-version 2 选择你要安装的发行版 这里我选择了Ubuntu18.04,获取后安装 启动安装的发行版即可 2. 使用WSL图形界面(可选) 设置环境变量 export DISPLAY=$(awk '/nameserver / {print $2; exit}' /etc/resolv.conf 2>/dev/null):0 export LIBGL_ALWAYS_INDIRECT=1 安装Xserver,这里选择的软件是vcxsrv, 可在sourceforge中下载安装。 安装完成后直接启动即可...

June 1, 2021 · 1 min · 李昌

go generate工具

1. go generate go generate命令运行时,将找到源代码中所有包含//go:generate的特殊注释,提取并执行//go:generate后附加的命令。 基本语法: //go:generate [-run regexp] [-n] [-v] [-x] [build flags] [file.go... | packages] 需要注意的几点: 该特殊注释必须在.go源码文件中。 每个源码文件可以包含多个generate特殊注释。 go generate只在运行go generate命令时运行,go build, go get, go test等其他命令不会运行它。 命令串行执行的,如果出错,就终止后面的执行。 特殊注释必须以"//go:generate"开头,双斜线后面没有空格。 简单的例子: package main import "fmt" //go:generate echo "world" func main() { fmt.Println("hello") } 运行结果: 在go generate命令中,还可以使用一些环境变量: $GOARCH The execution architecture (arm, amd64, etc.) $GOOS The execution operating system (linux, windows, etc.) $GOFILE The base name of the file....

May 27, 2021 · 3 min · 李昌

golang中context包的使用

context包定义了Context类型,这个类型在API边界即进程中传递截止日期、同步信号,请求值等相关信息。 1. 对context包的介绍 在服务器的传入请求中应包含context,而对服务器的传出调用应接收一个context。它们之间的调用链必须包含context,或是衍生的WithCancel, WithDeadline, WithTimeout, WithValue。当一个WithCancel Context被“cancel”,那么当前context所派生的所有context也都将被取消。 WithCancel, WithDeadline, WithTimeout接收一个Context对象(父对象),并返回其父对象的一个携带有cancel/deadline/timeout的一个拷贝(子对象)。调用CancelFunc会取消其子对象及子对象的子对象等,删除父对象对子对象的引用,并停止所有关联的计时器。未能调用CancelFunc将造成父对象结束前或计时器被触发前子对象的泄露。使用go vet工具可以检查所有控制流路径上是否都使用了CancelFunc 使用context的程序应遵循以下规则,以使各个包之间的接口保持一致,并启用静态分析工具来检查上下文传播: 不要将context存储在结构类型中,而是将context明确传递给需要它的每个函数。Context应该是第一个函数,通常命名为ctx。 func DoSomething(ctx context.Context, arg Arg) error { // ...use ctx... } 不要传递一个值为nil的context,即使一个函数允许这样做。如果你不确定Context的作用那就请传递context.TODO。 只在进程和API间传递请求范围数据时使用context值,不要用于将可选参数传递给函数。 同样的Context可以传递给运行在不同goroutine中的函数,Context是线程安全的。 2. Context接口 type Context interface { Done() <-chan struct{} Err() error Deadline() (deadline time.Time, ok bool) Value(key interface{}) interface{} } Context是一个接口,其定义非常的简单,只包含4个方法: Done() <-chan struct{} Done()方法将一个channel作为取消信号返回给持有context的函数,当该channel被关闭(即Done()被调用),这些函数应该立即停止其工作并返回。 Err() error Err()返回一个Error,说明为什么取消context。如果Done()没有被调用,那么Err返回nil。 Deadline() (deadline time.Time, ok bool) Deadline()方法返回持有这个context的函数的预期结束时间。如果并没有设置deadline,那么返回的ok将被设置为false。...

May 23, 2021 · 3 min · 李昌

Golang中反射reflect的基本使用

在计算机领域,反射是指一类应用,它们能够自描述和自控制。也即是说,这类应用通过采用某种机制来实现对自己行为的描述和监测,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。 反射(reflect)让我们能在运行期探知对象的类型信息和内存结构,这从一定程度上弥(mi)补了静态语言在动态行为上的不足。 反射(reflect)是在计算机程序运行时,访问,检查,修改它自身的一种能力,是元编程的一种形式。 Go语音提供了一种机制在运行时更新变量和检查它们的值、调用它们的方法和它们支持的内在操作,但是在编译时并不知道这些变量的具体类型。这种机制被称为反射。反射也可以让我们将类型本身作为第一类的值类型处理。 1. 为何我们需要反射? fmt.Fprintf函数提供字符串格式化处理逻辑,它可以对任意类型的值格式化并打印,甚至支持用户自定义的类型。 让我们也来尝试实现一个类似功能的函数。为了简单起见,我们的函数只接收一个参数,然后返回和fmt.Sprint类似的格式化后的字符串。我们实现的函数名也叫Sprint。 这里我们使用switch类型分支来对不同的类型进行处理。 func Sprint(x interface{}) string { type stringer interface { String() string } switch x := x.(type) { case stringer: return x.String() case string: return x case int: return strconv.Itoa(x) // ...similar cases for int16, uint32, and so on... case bool: if x { return "true" } return "false" default: // array, chan, func, map, pointer, slice, struct return "?...

May 22, 2021 · 4 min · 李昌

zsh的基本配置

1. 按照Oh my zsh $ sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" 2. 配置Oh my zsh 将zsh设置为默认Shell (脚本的最后一般会问你是否切换) chsh -s /bin/zsh # 不需要使用root权限 更换主题 vim ~/.zshrc 找到ZSH_THEME='robbyrussell', 更换为你想要使用的主题,可以在这里找到你想要的主题 安装插件 vim ~/.zshrc 找到plugins=(), 添加插件名称,我这里添加的插件有: plugins=(git zsh-autosuggestions zsh-syntax-highlighting) git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting git clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions 完成 source ~/.zshrc # 启动zsh 3. 使用主题powerlevel10k 下载主题 git clone --depth=1 https://gitee.com/romkatv/powerlevel10k.git ${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/themes/powerlevel10k 打开你的~/.zshrc,将主题换为:powerlevel10k/powerlevel10k 更改保存并使用主题 source ~/.zshrc 这时powerlevel10k会自动启动,询问你想要的配置 按照提示配置你想要的风格即可

May 20, 2021 · 1 min · 李昌