-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'smart-contract' into 'master'
Smart contract See merge request open-platform/chain!261
- Loading branch information
Showing
31 changed files
with
425 additions
and
61 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...tcontract/annotation/ContractConstruct.kt → ...ract/core/annotation/ContractConstruct.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
package io.openfuture.chain.smartcontract.annotation | ||
package io.openfuture.chain.smartcontract.core.annotation | ||
|
||
@Target(AnnotationTarget.FUNCTION) | ||
annotation class ContractConstruct |
2 changes: 1 addition & 1 deletion
2
...martcontract/annotation/ContractMethod.kt → ...ontract/core/annotation/ContractMethod.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
package io.openfuture.chain.smartcontract.annotation | ||
package io.openfuture.chain.smartcontract.core.annotation | ||
|
||
@Target(AnnotationTarget.FUNCTION) | ||
annotation class ContractMethod |
2 changes: 1 addition & 1 deletion
2
...rtcontract/exception/RequiredException.kt → ...tract/core/exception/RequiredException.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
package io.openfuture.chain.smartcontract.exception | ||
package io.openfuture.chain.smartcontract.core.exception | ||
|
||
class RequiredException(message: String?) : SmartContractException(message ?: "Required Exception") |
2 changes: 1 addition & 1 deletion
2
...tract/exception/SmartContractException.kt → .../core/exception/SmartContractException.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
package io.openfuture.chain.smartcontract.exception | ||
package io.openfuture.chain.smartcontract.core.exception | ||
|
||
abstract class SmartContractException(message: String) : RuntimeException("Smart contract exception: $message") |
2 changes: 1 addition & 1 deletion
2
...ture/chain/smartcontract/model/Address.kt → ...chain/smartcontract/core/model/Address.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...future/chain/smartcontract/model/Event.kt → ...e/chain/smartcontract/core/model/Event.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...ture/chain/smartcontract/model/Message.kt → ...chain/smartcontract/core/model/Message.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
package io.openfuture.chain.smartcontract.model | ||
package io.openfuture.chain.smartcontract.core.model | ||
|
||
class Message(val data: ByteArray, val value: Long, val sender: Address) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
23 changes: 23 additions & 0 deletions
23
src/main/kotlin/io/openfuture/chain/smartcontract/core/service/Services.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package io.test.io.openfuture.chain.smartcontract.core.service | ||
|
||
import io.openfuture.chain.smartcontract.core.model.SmartContract | ||
|
||
interface ContractService { | ||
|
||
fun get(address: String): SmartContract | ||
|
||
} | ||
|
||
interface TransactionService { | ||
|
||
fun transfer(senderAddress: String, recipientAddress: String, amount: Long) | ||
|
||
} | ||
|
||
interface BlockService { | ||
|
||
fun blockHash(height: Long): String | ||
|
||
fun blockTimestamp(height: Long): String | ||
|
||
} |
2 changes: 1 addition & 1 deletion
2
...chain/smartcontract/utils/AddressUtils.kt → .../smartcontract/core/utils/AddressUtils.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
11 changes: 11 additions & 0 deletions
11
src/main/kotlin/io/openfuture/chain/smartcontract/core/utils/ByteUtils.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package io.openfuture.chain.smartcontract.core.utils | ||
|
||
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils | ||
|
||
object ByteUtils { | ||
|
||
fun toHexString(bytes: ByteArray): String = ByteUtils.toHexString(bytes) | ||
|
||
fun fromHexString(hex: String): ByteArray = ByteUtils.fromHexString(hex) | ||
|
||
} |
2 changes: 1 addition & 1 deletion
2
...re/chain/smartcontract/utils/HashUtils.kt → ...ain/smartcontract/core/utils/HashUtils.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
28 changes: 28 additions & 0 deletions
28
src/main/kotlin/io/openfuture/chain/smartcontract/deploy/domain/ClassSource.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package io.openfuture.chain.smartcontract.deploy.domain | ||
|
||
import io.openfuture.chain.smartcontract.deploy.utils.asPackagePath | ||
import org.objectweb.asm.ClassReader | ||
import org.objectweb.asm.ClassWriter | ||
import org.objectweb.asm.Opcodes.ASM6 | ||
import java.nio.file.Path | ||
|
||
|
||
class ClassSource( | ||
val bytes: ByteArray | ||
) { | ||
|
||
companion object { | ||
fun isClass(path: Path): Boolean = path.fileName.toString().endsWith(".class", true) | ||
} | ||
|
||
val reader = ClassReader(bytes) | ||
val writer = ClassWriter(reader, ASM6) | ||
|
||
/** | ||
* Fully qualified class name, e.g. io.openfuture.chain.HelloWorld | ||
*/ | ||
val qualifiedName | ||
get() = reader.className.asPackagePath | ||
|
||
|
||
} |
6 changes: 6 additions & 0 deletions
6
src/main/kotlin/io/openfuture/chain/smartcontract/deploy/domain/LoadedClass.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package io.openfuture.chain.smartcontract.deploy.domain | ||
|
||
class LoadedClass( | ||
val clazz: Class<*>, | ||
val byteCode: ByteArray | ||
) |
6 changes: 6 additions & 0 deletions
6
src/main/kotlin/io/openfuture/chain/smartcontract/deploy/exception/ClassLoadingException.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package io.openfuture.chain.smartcontract.deploy.exception | ||
|
||
class ClassLoadingException( | ||
message: String? = "Class loading failed", | ||
cause: Throwable? = null | ||
) : RuntimeException(message, cause) |
90 changes: 90 additions & 0 deletions
90
src/main/kotlin/io/openfuture/chain/smartcontract/deploy/load/SourceClassLoader.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
package io.openfuture.chain.smartcontract.deploy.load | ||
|
||
import io.openfuture.chain.smartcontract.deploy.domain.ClassSource.Companion.isClass | ||
import io.openfuture.chain.smartcontract.deploy.domain.LoadedClass | ||
import io.openfuture.chain.smartcontract.deploy.exception.ClassLoadingException | ||
import io.openfuture.chain.smartcontract.deploy.utils.asResourcePath | ||
import io.openfuture.chain.smartcontract.deploy.utils.toURL | ||
import org.slf4j.Logger | ||
import org.slf4j.LoggerFactory | ||
import java.io.FileNotFoundException | ||
import java.io.IOException | ||
import java.net.URL | ||
import java.net.URLClassLoader | ||
import java.nio.file.Files | ||
import java.nio.file.Path | ||
import java.nio.file.Paths | ||
|
||
|
||
class SourceClassLoader( | ||
paths: List<Path> = emptyList() | ||
) : URLClassLoader(resolvePaths(paths), getSystemClassLoader()) { | ||
|
||
companion object { | ||
private val log: Logger = LoggerFactory.getLogger(SourceClassLoader::class.java) | ||
} | ||
|
||
private val classes: MutableMap<String, LoadedClass> = mutableMapOf() | ||
|
||
|
||
override fun loadClass(name: String): Class<*> = loadClass(name, false) | ||
|
||
override fun loadClass(name: String, resolve: Boolean): Class<*> { | ||
try { | ||
//todo validate | ||
return super.loadClass(name, resolve) | ||
} catch (ex: Throwable) { | ||
throw ClassLoadingException(ex.message, ex) | ||
} | ||
} | ||
|
||
override fun findClass(name: String): Class<*> { | ||
val loadedClass = classes[name] | ||
if (null != loadedClass) { | ||
log.trace("Class $name already loaded") | ||
return loadedClass.clazz | ||
} | ||
|
||
val bytes = readClassBytes(name) | ||
val clazz = loadBytes(name, bytes).clazz | ||
classes[name] = LoadedClass(clazz, bytes) | ||
resolveClass(clazz) | ||
return clazz | ||
} | ||
|
||
fun loadBytes(className: String, bytes: ByteArray): LoadedClass { | ||
try { | ||
return LoadedClass(defineClass(className, bytes, 0, bytes.size), bytes) | ||
} catch (ex: Throwable) { | ||
throw ClassLoadingException(ex.message, ex) | ||
} | ||
} | ||
|
||
private fun readClassBytes(fullyQualifiedClassName: String): ByteArray { | ||
try { | ||
return (getResourceAsStream("${fullyQualifiedClassName.asResourcePath}.class") | ||
?: throw ClassLoadingException("Class not found $fullyQualifiedClassName")).readBytes() | ||
} catch (e: IOException) { | ||
throw ClassLoadingException("Error reading bytecode", e) | ||
} | ||
} | ||
|
||
} | ||
|
||
|
||
private val homeDirectory: Path | ||
get() = Paths.get(System.getProperty("user.home")) | ||
|
||
|
||
private fun resolvePaths(paths: List<Path>): Array<URL> = paths.map { expandPath(it) }.flatMap { path -> | ||
when { | ||
!Files.exists(path) -> throw FileNotFoundException("File not found; $path") | ||
isClass(path) || Files.isDirectory(path) -> listOf(path.toURL()) | ||
else -> throw IllegalArgumentException("Expected a class file, but found $path") | ||
} | ||
}.toTypedArray() | ||
|
||
private fun expandPath(path: Path): Path = if (path.toString().startsWith("~/")) { | ||
homeDirectory.resolve(path.toString().removePrefix("~/")) | ||
} else path | ||
|
24 changes: 24 additions & 0 deletions
24
src/main/kotlin/io/openfuture/chain/smartcontract/deploy/service/DefaultContractService.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package io.openfuture.chain.smartcontract.deploy.service | ||
|
||
import io.openfuture.chain.smartcontract.deploy.domain.ClassSource | ||
import io.openfuture.chain.smartcontract.deploy.load.SourceClassLoader | ||
import org.springframework.stereotype.Service | ||
|
||
@Service | ||
class DefaultContractService : ContractService { | ||
|
||
private val classLoader = SourceClassLoader() | ||
|
||
|
||
override fun deploy(bytes: ByteArray) { | ||
// simple deploy method | ||
val source = ClassSource(bytes) | ||
classLoader.loadBytes(source.qualifiedName, bytes) | ||
} | ||
|
||
override fun run(className: String, method: String, vararg params: Any) { | ||
//run a method of a contract in separate thread | ||
TODO("not implemented") | ||
} | ||
|
||
} |
9 changes: 9 additions & 0 deletions
9
src/main/kotlin/io/openfuture/chain/smartcontract/deploy/service/Services.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package io.openfuture.chain.smartcontract.deploy.service | ||
|
||
interface ContractService { | ||
|
||
fun deploy(bytes: ByteArray) | ||
|
||
fun run(className: String, method: String, vararg params: Any) | ||
|
||
} |
9 changes: 9 additions & 0 deletions
9
src/main/kotlin/io/openfuture/chain/smartcontract/deploy/utils/Extentions.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package io.openfuture.chain.smartcontract.deploy.utils | ||
|
||
import java.net.URL | ||
import java.nio.file.Path | ||
|
||
fun Path.toURL(): URL = this.toUri().toURL() | ||
|
||
val String.asPackagePath: String get() = this.replace('/', '.') | ||
val String.asResourcePath: String get() = this.replace('.', '/') |
31 changes: 31 additions & 0 deletions
31
src/main/kotlin/io/openfuture/chain/smartcontract/deploy/validation/BlackList.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package io.test.io.openfuture.chain.smartcontract.deploy.validation | ||
|
||
object BlackList { | ||
|
||
private val entries = setOf( | ||
"java/awt/.*", | ||
"java/beans/.*", | ||
"java/lang/invoke/.*", | ||
"java/lang/.*Thread.*", | ||
"java/lang/Shutdown.*", | ||
"java/lang/ref/.*", | ||
"java/lang/reflect/InvocationHandler.*", | ||
"java/lang/reflect/Proxy.*", | ||
"java/lang/reflect/Weak.*", | ||
"java/io/.*File.*", | ||
"java/net/.*Content.*", | ||
"java/net/Host.*", | ||
"java/net/Inet.*", | ||
"java/nio/file/Path.*", | ||
"java/nio/file/attribute/.*", | ||
"java/util/SplittableRandom.*", | ||
"java/util/Random.*", | ||
"java/util/WeakHashMap.*", | ||
"java/util/concurrent/.*", | ||
"java/util/concurrent/locks/.*", | ||
"javax/activation/.*" | ||
).map { "[\\(\\)L]?$it".toRegex() } | ||
|
||
fun matches(className: String): Boolean = entries.any { it.matches(className) } | ||
|
||
} |
Oops, something went wrong.