Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions packages/ruby/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# upsideos_evm_rwa_artifacts

ABIs and verification sources for the audited EVM Security Token releases.
ABIs, creation code and verification sources for the audited EVM Security
Token releases.

The gem carries data only. It has no dependencies, and it ships the same
files as the `@upsideos/evm-rwa-artifacts` npm package, built from the
Expand Down Expand Up @@ -36,6 +37,17 @@ call surface when you talk to the token address:
UpsideosEvmRwaArtifacts.merged_abi('v5', 'RestrictedLockupToken')
```

## Deploy a contract

`artifact` returns the ABI together with the creation code, in the shape a
deployment front end reads. `bytecode` returns the creation code alone, as
the 0x-prefixed hex a deployment transaction carries:

```ruby
UpsideosEvmRwaArtifacts.artifact('v5.1', 'RestrictedLockupToken')
UpsideosEvmRwaArtifacts.bytecode('v5.1', 'RestrictedLockupToken')
```

## Verify a deployment

`verification_source_codes` returns the solc standard-json bundle that an
Expand Down Expand Up @@ -69,9 +81,8 @@ Digest::SHA256.hexdigest(path.binread)

## What the gem leaves out

The gem ships no bytecode and no tooling, because a Ruby consumer reads
contracts and verifies them but does not compile or deploy them. Use the
npm package for deployment bytecode, and `@upsideos/evm-explorer-verify`
The gem ships no tooling, because a Ruby consumer reads contracts and
hands them on but does not compile them. Use `@upsideos/evm-explorer-verify`
to submit a verification to an explorer.

## Notes
Expand Down
19 changes: 18 additions & 1 deletion packages/ruby/lib/upsideos_evm_rwa_artifacts.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@

require_relative 'upsideos_evm_rwa_artifacts/version'

# ABIs and verification sources for audited EVM contract releases.
# ABIs, creation code and verification sources for audited EVM contract
# releases.
#
# The gem carries data only. It has no dependencies and runs no code at
# load time beyond reading the release directory.
Expand Down Expand Up @@ -54,6 +55,12 @@ def abi_path(release, contract)
path(release, "abi/#{contract}.json")
end

# The ABI together with the creation code, in the shape a deployment
# front end reads: abi, bytecode, deployedBytecode, immutableReferences.
def artifact_path(release, contract)
path(release, "artifacts/#{contract}.json")
end

# The token forwards unknown selectors into its extensions, so a caller
# that talks to the token address needs the merged call surface rather
# than the token ABI alone.
Expand All @@ -77,6 +84,16 @@ def merged_abi(release, contract)
read_json(merged_abi_path(release, contract))
end

def artifact(release, contract)
read_json(artifact_path(release, contract))
end

# The creation code, as the 0x-prefixed hex a deployment transaction
# carries. Constructor arguments append to it.
def bytecode(release, contract)
artifact(release, contract).fetch('bytecode')
end

def verification_source_codes(release)
read_json(verification_source_codes_path(release))
end
Expand Down
2 changes: 1 addition & 1 deletion packages/ruby/lib/upsideos_evm_rwa_artifacts/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module UpsideosEvmRwaArtifacts
VERSION = '0.1.1'
VERSION = '0.2.0'
end
24 changes: 12 additions & 12 deletions packages/ruby/script/prepare_data.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@

# Copy the data the gem ships out of the release directories.
#
# The gem carries ABIs, manifests and verification sources. It leaves out
# the bytecode in artifacts/, because a Ruby consumer reads contracts and
# verifies them but does not deploy them.
# The gem carries ABIs, artifacts, manifests and verification sources. A
# Ruby consumer hands the creation code to a browser that deploys the set,
# so the artifacts come along with the ABIs.

require 'fileutils'
require 'pathname'
Expand All @@ -29,17 +29,17 @@ def copy_release(release)
FileUtils.cp(source.join(file), target.join(file))
end

FileUtils.mkdir_p(target.join('abi'))
Dir[source.join('abi', '*.json')].each do |abi|
FileUtils.cp(abi, target.join('abi', File.basename(abi)))
end
copy_json_dir(source.join('abi'), target.join('abi'))
copy_json_dir(source.join('artifacts'), target.join('artifacts'))
copy_json_dir(source.join('abi', 'merged'), target.join('abi', 'merged'))
end

merged = source.join('abi', 'merged')
return unless merged.directory?
def copy_json_dir(source, target)
return unless source.directory?

FileUtils.mkdir_p(target.join('abi', 'merged'))
Dir[merged.join('*.json')].each do |abi|
FileUtils.cp(abi, target.join('abi', 'merged', File.basename(abi)))
FileUtils.mkdir_p(target)
Dir[source.join('*.json')].each do |file|
FileUtils.cp(file, target.join(File.basename(file)))
end
end

Expand Down
34 changes: 30 additions & 4 deletions packages/ruby/test/upsideos_evm_rwa_artifacts_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,35 @@ def test_unknown_contract
assert_raises(UpsideosEvmRwaArtifacts::UnknownFile) { UpsideosEvmRwaArtifacts.abi('v5', 'NoSuchContract') }
end

# The gem is data only. Bytecode belongs to the npm package, because a
# Ruby consumer reads and verifies contracts but does not deploy them.
def test_no_bytecode_ships
assert_empty Dir[UpsideosEvmRwaArtifacts::DATA_ROOT.join('**', 'artifacts', '*')]
def test_bytecode_is_prefixed_hex
bytecode = UpsideosEvmRwaArtifacts.bytecode('v5', 'AccessControl')

assert_match(/\A0x[0-9a-f]+\z/, bytecode)
end

def test_artifact_carries_the_same_abi_as_the_abi_file
artifact = UpsideosEvmRwaArtifacts.artifact('v5.1', 'RestrictedLockupToken')

assert_equal UpsideosEvmRwaArtifacts.abi('v5.1', 'RestrictedLockupToken'), artifact.fetch('abi')
end

# The manifest digests the creation code as raw bytes, so a truncated or
# re-encoded copy in the gem shows up here.
def test_shipped_creation_code_matches_the_manifest_digests
UpsideosEvmRwaArtifacts.releases.each do |release|
UpsideosEvmRwaArtifacts.manifest(release).fetch('artifacts').each do |entry|
name = entry.fetch('name')
creation = entry.fetch('creationCode')
bytes = [UpsideosEvmRwaArtifacts.bytecode(release, name).delete_prefix('0x')].pack('H*')

assert_equal creation.fetch('length'), bytes.length, "#{release} #{name} creation code length"
assert_equal creation.fetch('sha256'), Digest::SHA256.hexdigest(bytes),
"#{release} #{name} creation code digest"
end
end
end

def test_unknown_contract_artifact
assert_raises(UpsideosEvmRwaArtifacts::UnknownFile) { UpsideosEvmRwaArtifacts.artifact('v5', 'NoSuchContract') }
end
end
Loading